<?xml version="1.0" encoding="utf-8"?>
<search>
  
  
  
  <entry>
    <title>我使用过的笔记类软件对比</title>
    <link href="/2022/07/30/%E6%88%91%E4%BD%BF%E7%94%A8%E8%BF%87%E7%9A%84%E7%AC%94%E8%AE%B0%E7%B1%BB%E8%BD%AF%E4%BB%B6%E5%AF%B9%E6%AF%94/"/>
    <url>/2022/07/30/%E6%88%91%E4%BD%BF%E7%94%A8%E8%BF%87%E7%9A%84%E7%AC%94%E8%AE%B0%E7%B1%BB%E8%BD%AF%E4%BB%B6%E5%AF%B9%E6%AF%94/</url>
    
    <content type="html"><![CDATA[<p>不同软件有不同的使用场景，我可能也没有体验到所有的功能，以下仅代表个人的使用体验</p><table><thead><tr><th>软件</th><th>优点</th><th>缺点</th></tr></thead><tbody><tr><td>手机备忘录</td><td>打开手机可以随身随地记录，打开非常迅速快捷</td><td>用过华为和小米的手机，笔记只能在同一款机型下同步</td></tr><tr><td>记事本</td><td>txt文件 适用于简单的记录</td><td>仅限简单的记录</td></tr><tr><td>word</td><td>办公软件不多说<br>最新的word的全屏模式也很舒服</td><td>没办法形成笔记系统，不能在多文件直接快速切换</td></tr><tr><td>有道云笔记</td><td>我当时发现的第一款云笔记就觉得非常好用<br>云笔记保证了可以在多平台同步</td><td>实在觉得UI设计不太舒服<br>markdown还在左右分栏编辑<br>付费也有</td></tr><tr><td>印象笔记</td><td>看过很多说印象笔记好的<br>也有超多的优点</td><td>觉得想系统的知识体系很耗时间，因为要有自己的分类和编号什么的</td></tr><tr><td>typora</td><td>markdown编辑神器 所见即所得<br>程序员必备</td><td>图片只能在本地，分享不方便<br>图床又很麻烦</td></tr><tr><td>幕布</td><td>笔记采用极简模式</td><td>太简单 也不好看</td></tr><tr><td>OneNote</td><td>这是一款我曾经觉得可以一直不换的笔记软件<br>全平台云端实时同步<br>点击任意位置可进行编辑<br>还能作为白板，无限画布，手写笔记和讲课板书很方便</td><td>没办法代码高亮 不适合程序员<br>编辑排版不太顺手</td></tr><tr><td>石墨文档</td><td>用过表格多人协作</td><td>不喜欢的有些界面</td></tr><tr><td>腾讯文档</td><td>主要用于多人协作表格 表单收集等<br>支持表格隐私保护<br>几百人同时访问一个文档都可以</td><td>适用于特定应用场景</td></tr><tr><td>CSDN</td><td>技术人的交流社区，用写博客的方式记笔记也是很方便的</td><td>包括博客园或者个人博客等，更适合技术上的公开分享</td></tr><tr><td>drawboard pdf</td><td>pdf批注工具 限时优惠的时候白嫖了一下，用于pdf批注非常好用，考研的时候用的多一些</td><td>平板下不了这个软件</td></tr><tr><td>obisdian</td><td>可以说是本地markdown文件的管理器，也就保证了本地安全<br>支持文档间引用 文档关系图<br>开源 强大的插件库</td><td>云同步需要付费 就很难全平台了</td></tr><tr><td>notion</td><td>全网都在抄的笔记软件<br>块级思想block承载一切<br>用好了绝对是个效率神奇</td><td>服务器在国外 华为平板下不了软件<br>团队用付费<br>没有页面内导航，但可以用浏览器插件<br>不支持思维导图</td></tr><tr><td>思源笔记</td><td>功能强大 可以本地部署</td><td>界面还是不太喜欢</td></tr><tr><td>语雀</td><td>一上手就觉得极度舒适<br>支持插入思维导图和白板绘图</td><td>可能语雀的定位是博客 在尝试团队管理的时候很不顺手<br>语雀的工作台很不舒服</td></tr><tr><td>wolai</td><td>深度体验了一个月，甚至我还开了会员，体验很舒适，也用它进行多人协同和管理<br><br>最喜欢的几个功能<br>1.页面双链引用，页面关系图（notion没有），页面跳转<br>2.思维导图在线制作（notion没有），<br>3.公式图片识别自动转latex 很强<br>4.数据表格筛选，多视图，引用数据表格<br>5.页面多人协作，视角跟随，页面评论，项目协作<br>6.允许插入文件，公开分享，下载<br>7.搜索功能，图片OCR，可搜索图片内容8.手机平板电脑实时多端同步<br>9.国内的服务器，不用考虑网络问题（相比notion)<br>10.支持markdown语法，脚注，颜色（相比typora）<br>11.微信剪藏，转发到wolai助手自动分类保存<br>12.支持嵌入腾讯会议，processon等几十款应用<br>13.夜间模式， 标题目录（notion没有），代码高亮</td><td>无法实现文件系统管理<br>可以上传文件只能预览不能在线编辑<br>付费功能使用更佳<br>团队协作权限管理还是有很多痛点<br>希望能增加白板绘图<br>暂不支持数据表格日历视图，正在开发</td></tr><tr><td>FlowUS</td><td>跟wolai差不多，都是类似于notion的笔记软件 使用体验可能要超过wolai<br>亮点：支持文件管理 小组版5人免费 UI体验更舒适 针对学生模板更丰富<br>专业版比wolai便宜，而且存储无限 协作无限</td><td>对比wolai <br>不支持思维导图<br>公式不支持识别生成<br>没有图片OCR<br>好像暂不支持微信剪藏</td></tr><tr><td>钉钉云文档</td><td>在钉钉的平台 说几个亮点<br>集人员沟通 团队管理 文档协作于一身<br>实现了文档管理 在线编辑自己上传的文件 也可以在里面新建文件，文件之间可以双链引用 而且有文档关系图</td><td>钉钉的功能过于强大复杂，不像wolai那么简洁<br>更多面向企业团队的管理是我们学生管理不需要的</td></tr><tr><td>飞书</td><td>没有深度体验过 但是全网在吹 很难与钉钉做一个取舍<br>用好了会比wolai的协作更高效，准备再深度体验一下</td><td>群里等不同于微信的使用习惯，上手还需要适应</td></tr><tr><td>mindmaster</td><td>用思维导图记笔记，功能很强大，考研的时候用的比较多，梳理知识点</td><td>想做一个大图的时候就要付费了</td></tr></tbody></table><p>顺便对比一下在用的文献阅读工具</p><table><thead><tr><th>软件</th><th align="left">优点</th><th align="left">缺点</th></tr></thead><tbody><tr><td>cajViewer</td><td align="left">caj文件快速阅读</td><td align="left">不适合文献管理</td></tr><tr><td>知网研学</td><td align="left">云同步 文献管理 文献笔记<br>文献矩阵</td><td align="left">适合中文文献</td></tr><tr><td>知云文献翻译</td><td align="left">使用稳定 有水印也能稳定选中<br>怕pdf复制有换行 用知云打开就好了</td><td align="left">本地使用</td></tr><tr><td>小绿鲸</td><td align="left">很好的在线阅读文献+翻译工具</td><td align="left">每篇文献不是唯一网址，其他没有深度使用</td></tr><tr><td>readpaper</td><td align="left">在线搜索文献 有pdf可以直接阅读<br>也可以看别人记的笔记<br>选中在线翻译 记笔记 在线同步<br>每篇文章都有唯一网址  在其他地方可以直线访问<br>客户端可以集成搜索引擎</td><td align="left">最近刚成长起来的软件 使用顺手的细节设计和文献矩阵还需要考虑</td></tr><tr><td>mendeley</td><td align="left">在线同步<br>自动提取文献的关键信息<br>与word结合插入参考文献<br>支持搜索到文件里面的内容</td><td align="left">看的时候不能翻译<br />但网页版可以配合浏览器插件【侧边翻译】翻译</td></tr><tr><td>网易有道词典</td><td align="left">学生认证可享全文免费翻译，快去白嫖<br>可以语法纠错和润色<br>取词 截屏翻译等都很方便</td><td align="left"></td></tr></tbody></table>]]></content>
    
    
    <categories>
      
      <category>随笔</category>
      
    </categories>
    
    
    <tags>
      
      <tag>随笔</tag>
      
      <tag>软件</tag>
      
    </tags>
    
  </entry>
  
  
  
  <entry>
    <title>图像处理中的抠图技术image matting</title>
    <link href="/2022/04/06/%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86%E4%B8%AD%E7%9A%84%E6%8A%A0%E5%9B%BE%E6%8A%80%E6%9C%AFimagematting/"/>
    <url>/2022/04/06/%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86%E4%B8%AD%E7%9A%84%E6%8A%A0%E5%9B%BE%E6%8A%80%E6%9C%AFimagematting/</url>
    
    <content type="html"><![CDATA[<h1 id="抠图技术（imagematting"><a href="#抠图技术（imagematting" class="headerlink" title="抠图技术（imagematting)"></a>抠图技术（imagematting)</h1><p><a href="https://so.csdn.net/so/search?q=%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86&spm=1001.2101.3001.7020">图像处理</a>中的image matting技术，中文简称抠图技术。Image Matting也是一个基本的计算机视觉问题，有着广泛的应用。</p><p>证件照换背景应该算是最简单的Image Matting，由于证件照背景属性的特殊性，这个抠图很容易可以实现。算法分为几个步骤： </p><span id="more"></span><ol><li>读入原始证件照图片</li><li>转换到HSV色彩空间（色调（H），饱和度（S），明度（V））</li><li>设置HSV空间的阈值获得图片背景的mask（抠图的结果）</li><li>腐蚀膨胀去除干扰点</li><li>遍历像素点替换背景颜色</li></ol><p><img src="https://s2.loli.net/2022/04/06/GWOaI6VLsQtBoJv.png" alt="image-20220406170054554"></p><p>使用python+opencv库可以很容易实现，有兴趣的可以自己了解一下</p><h2 id="抠图技术与图像分割有什么区别"><a href="#抠图技术与图像分割有什么区别" class="headerlink" title="抠图技术与图像分割有什么区别"></a>抠图技术与图像分割有什么区别</h2><p>刚接触这项技术时一直有些疑虑，这个和图像分割技术有什么差别，</p><p><img src="https://s2.loli.net/2022/04/06/iextvMWIP4nZqCr.png" alt="image-20220406170334652"></p><p>然后大概明白。<a href="https://so.csdn.net/so/search?q=%E5%9B%BE%E5%83%8F%E5%88%86%E5%89%B2&spm=1001.2101.3001.7020">图像分割</a>是将原图分割成若干块，分割的好与不好就看分出来的块是否与图像的内容对应了，例如如果分割结束后某一块只包含半张人脸，另外半张在另一块上，那肯定就不是好的分割了。至于抠图技术，基本只会分成两块，一块是前景，另一块是背景，而大多数时候我们抠图也就是为了把前景给拿出来。基本抠图都要人工交互，而分割技术则是全自动的，当然有人工介入的抠图分割在准确性上要远高于常规的图像分割技术，优秀的抠图算法是有能力将前景中非常细小的毛发细节都能提取出的好算法，这点是传统图像分割技术做不到的。也不少文章会将分割技术作为抠图的第一步融入进去。</p><h2 id="抠图技术早期应用"><a href="#抠图技术早期应用" class="headerlink" title="抠图技术早期应用"></a>抠图技术早期应用</h2><p>早期这项技术主要被用在电影工业中，所以这是一项古老的技术，只是现在依然在不断发展进步。你有时会看到拍电影的摄影棚都是全绿色背景，以及一群穿着全绿色衣服的工作人员。这些都会在后期的抠图技术下被抠掉换上“真正的”背景，这用的就是最原始的蓝屏抠图技术，即背景是纯色时用的抠图技术，纯色的背景可以确保前景被准确抠出。</p><p><img src="https://s2.loli.net/2022/04/06/B2aTUfph4oX6tgK.png" alt="image-20220406170433286"></p><p>不过纯色背景的情况在现实中太少，应用面狭窄，抠图技术重点在背景是自然图像的复杂图片。</p><p><img src="https://s2.loli.net/2022/04/06/BF2LUxj3PiQqXgI.png" alt="image-20220406170456389"></p><h2 id="复杂图片的image-matting"><a href="#复杂图片的image-matting" class="headerlink" title="复杂图片的image matting"></a>复杂图片的image matting</h2><p>在复杂图片的Image Matting课题上，主要包括经典的传统方法和近年来兴起的深度学习方法。</p><p>在<strong>传统方法</strong>部分，有比较典型的三种经典算法：</p><p>Bayesian Matting（贝叶斯抠图）</p><p>Closed Form Mating（闭型抠图）</p><p>KNN Matting（K近邻抠图）</p><p>而在<strong>深度学习</strong>方面的主要有</p><p>Deep Image Matting</p><p>AlphaGAN Matting</p><h2 id="抠图界的上帝公式"><a href="#抠图界的上帝公式" class="headerlink" title="抠图界的上帝公式"></a>抠图界的上帝公式</h2><p>图像或视频中的前景准确估计问题，在实际应用中具有十分重要的意义。它是图像编辑和电影制作中的一项关键技术。虽然这项古老的技术发展至今已经数十年了，但几乎所有的解决方案都是在想办法做成一件事情，把这个公式“C = αF + (1-α)B”给解出来，这个公式就是1996年Alvy Ray Smith等人的《Blue Screen Matting》的paper中正式定义的Image Matting问题提出的，可以把它称为抠图界的“上帝公式”。</p><p><img src="https://s2.loli.net/2022/04/06/LaOAEnwKfGmhvPC.png" alt="image-20220406170733934"></p><p>其中C是原始图像的像素（例如下面的左图就是一张待处理的图像），为已知量；α是透明度，F是前景像素（例如图中的人物），B是背景像素（例如图中的树丛），这三个变量为未知量。</p><p><img src="https://s2.loli.net/2022/04/06/vknm3b4zWDtHiTc.png" alt="image-20220406170829603"></p><p>对于这个公式的理解，我们可以把原始图像看做是前景和背景按照一定权重（α透明度）叠加组成的。对于完全确定是前景的像素，α = 1;对于完全确定是背景的像素，α=0; 但问题是我们不能100%确定每个像素它是否是属于前景或是背景，如果一个像素一个像素分析后你也确实可以确定哪个属于前景，哪个属于背景，但这时图也已经抠好了，计算机就没用了，这里也就引出了抠图技术真正需要计算机出马的部分了，就是处理在图像中那些人工不是那么容易辨认是前景还是背景的细节部分。不容易确定的部分则为未知区域由计算机处理。对于不确定是前景还是背景的像素，a是介于0到1之间的浮点数。 Image Matting问题研究的是，如何通过C，推测出未知的三个变量α、F和B，难度可想而知。</p><p>获取到每个像素的α值后就可以生成一张α图，这张图看起来是只有前景是白的，其余都是黑的，这就像是我们都曾见过的在艺术创作中使用的蒙版（matte），只把前景露出来，其他背景被挡住。它和原图结合后就完成了抠图的工作了。之后只要继续按照上帝公式就可将抠出的前景移到新的背景中了。读入一张新的背景图片（如下图中间所示），并将前景（经由α 矩阵）融合到新的背景中，最终结果如上图右所示。</p><p><img src="https://s2.loli.net/2022/04/06/WC3SUfQpVYcdHM6.png" alt="image-20220406170933405"></p><p>问题是一个等式解不出三个变量啊？</p><p>1996年Alvy Ray Smith等人的《Blue Screen Matting》给出了Triangulation Matting的方法，整体思想是：既然Image Matting原问题那么难，不如把条件放松，使得问题简单一些，假设我知道了 B和 C，那么有没有可能得到 α 和 F，于是作者提出针对同一张前景，切换背景，来应用最小二乘法，计算得到对应的透明度和前景。</p><p>2004年Jian Sun等人的《Poisson matting》开始在Image Matting课题上提出使用Trimap作为辅助工具。Trimap分为三种颜色，黑色代表完全背景（此处 α为0），白色代表完全前景（此处 α 为1），灰色代表不确定区域（ α为0.5），所以说trimap图就是包含前景、背景和未知区域的图。因为前面提到过由于方程是病态的，所以要有约束条件才有解，而Trimap就相当于约束条件，并且简化计算。自此，Image Matting变为下图所示过程：</p><p><img src="https://s2.loli.net/2022/04/06/m6jwo738hUDXMCO.png" alt="image-20220406171021447"></p><p>基本上所有在文献中的抠图算法都是在教计算机如何更准确更快地通过<strong>用户指定</strong>的前景和背景估计出未知区域的α、B、F，而用户指定的方式一般分为两种，一种是这种提到的信息量很大的trimap图，另一种则是信息量具少的草图（scribbles）。然而trimap图的构建是很麻烦的，用户需要几乎把整张图都涂满才行，而草图就方便很多，只要在前景和背景处画几笔即可。所以对草图的处理才是未来抠图技术的发展趋势。</p><p><img src="https://s2.loli.net/2022/07/26/KbvigEwfm8h6xD5.png" alt="image-20220406171056547"></p><p>近年来，随着<a href="https://so.csdn.net/so/search?q=%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0&spm=1001.2101.3001.7020">深度学习</a>技术的发展，使得Deep Learning在计算机视觉领域的应用变得越来越广泛。主要介绍2017年CVPR的Deep Image Matting和AlphaGAN。</p><h2 id="Deep-Image-Matting"><a href="#Deep-Image-Matting" class="headerlink" title="Deep Image Matting"></a>Deep Image Matting</h2><p><img src="https://s2.loli.net/2022/04/06/qHmktJLB6hSjTPs.png" alt="image-20220406171157371"></p><p>这个网络基于典型的Encoder-Decoder结构，做深度学习的应该比较熟悉这种结构在图像分割和以图得图的GAN（生成对抗网络）网络中最常见。Encoder用pre-trained的VGG16，把fc6从全连接换成了卷积，并在输入增加了第四通道channel4，用来存放输入的trimap，因为channel4而增加的weights全部初始化为0。Decoder用简单的unpooling（上池化）和convolution的组合来做upsampling（上采样）和空间结构推断。右边的refine network是为了解决第一阶段预测输出边缘blur（模糊）的情况。</p><p>值得一提的是这篇文章提出了两种Loss，这两种Loss分别是Alpha-prediction Loss和Compositional Loss。</p><p>Alpha-prediction Loss即Ground Truth α值和预测每个像素α 值之间的绝对差异。</p><p><img src="https://s2.loli.net/2022/04/06/19MbdpEUjSxe832.png" alt="image-20220406171804421"></p><p>Compositional Loss，即Ground Truth 前景、背景和预测alpha matting组成的预测RGB图片与Ground Truth RGB图片之间的绝对差异。</p><p><img src="https://s2.loli.net/2022/04/06/OMvheLU6b8TSI73.png" alt="image-20220406171825335"></p><p>而神经网络训练的Loss是由两种Loss加权，翻</p><p>在实验中作者设置 ω l = 0.5 ，即两种Loss的贡献一样。</p><p><img src="https://s2.loli.net/2022/04/06/Lnlo3j9EUehWRXz.png" alt="image-20220406171840665"></p><h2 id="AlphaGAN"><a href="#AlphaGAN" class="headerlink" title="AlphaGAN"></a>AlphaGAN</h2><p>基于前面Deep Image Matting的启发，我们知道Image Matting这个任务本质上是一个以图得图的任务，而处理这种任务最常见的就是图像分割和GAN（生成对抗网络）。这里我们选择接着探究GAN网络在Image Matting问题上的应用。</p><p>（生成对抗网络GAN由生成网络G(Generator)和判别网络D(Discriminator)组成。在训练过程中，生成网络G的目标是尽量生成真实的图片去欺骗判别网络D。而D的目标是尽量把G生成的图片和真实的图片区分开来。这样G和D构成了一个动态的“零和博弈”。GAN就是通过Generator和discriminator进行零和博弈，来不断生成，不断欺骗来获得更好的效果。）</p><p>2018年BMVC有一篇论文：AlphaGAN。这篇文章是基于前面的Deep Image Matting做的。AlphaGAN matting 很大程度上借鉴了Deep Image matting。</p><p>AlphaGAN matting 将Deep Image matting中的深度网络拿来作为了GAN的generator，改进只是只是把encoder中的VGG16换成了ResNet50，并把少部分卷积层替换，采用的损失函数和上面提到的loss一致。AlphaGAN matting 的discriminator采用PatchGAN，也是以图得图问题中比较先进且常用的discriminator （鉴别器）。PatchGAN对图片中每个N×N的小块(Patch)计算概率，然后将这些概率求平均值作为整体的输出，这样做可以加快速度以及加快收敛。</p><h2 id="结合显著性检测自动生成Trimap"><a href="#结合显著性检测自动生成Trimap" class="headerlink" title="结合显著性检测自动生成Trimap"></a>结合显著性检测自动生成Trimap</h2><p>到目前为止，大家都能看出来Image Matting最大的弊端：给定一张图，需要一张手工标记的trimap才能开始Image Matting。</p><h3 id="手动生成trimap"><a href="#手动生成trimap" class="headerlink" title="手动生成trimap"></a>手动生成trimap</h3><p>前面提到的Image Matting方法都需要手工标注的Trimap才可以进行抠图。而这些trimap大多依赖手工标记生成，如利用Photoshop （PS）等，但这些专业的图像操作软件对于普通人利用起来并非易事。于是网上也有封装好的Robust Matting程序来协助我们手工标记来生成trimap。</p><p>下面我们讨论怎样让trimap的生成变得更加智能。</p><h3 id="自动生成trimap"><a href="#自动生成trimap" class="headerlink" title="自动生成trimap"></a>自动生成trimap</h3><p>我们想到用显著图（saliency map）结合一些图像处理方法来实现从原始图片到trimap，再从trimap到图。从而实现只需要给定一张原始图片，就可以输出抠完图的结果。</p><p>算法流程：</p><p>1利用目前比较先进的显著物体检测算法（salient object detection）来得到显著图。</p><p>2对显著图进行阈值分割，粗略地划分前景区域和背景区域。</p><p>3对得到的二值图分别进行一次腐蚀和一次膨胀操作。</p><p>4两次操作的差记为未知区域。</p><p>5由前景区域、背景区域、未知区域生成trimap。</p><h2 id="实验结果"><a href="#实验结果" class="headerlink" title="实验结果"></a>实验结果</h2><p>在对标准数据集的图片进行测试后，我们采用自己找来的图片来提取trimap后利用之前提到的四种方法进行抠图，实验效果如下图所示，相关结果也比较优秀。</p><p><img src="https://s2.loli.net/2022/04/06/rydFRL6W7bkV1Sw.png" alt="image-20220406172347020"></p><p>最后是我们提出的利用显著性检测来实现对一些图片生成trimap的结果展示，可以看出在一些显著性比较明显的图片上，trimap生成也还不错：</p><p><img src="https://s2.loli.net/2022/04/06/E3Cq5MwmfheScgP.png" alt="image-20220406172400279"></p><h1 id="贝叶斯抠图"><a href="#贝叶斯抠图" class="headerlink" title="贝叶斯抠图"></a>贝叶斯抠图</h1><h2 id="引言"><a href="#引言" class="headerlink" title="引言"></a>引言</h2><p>这里要讲的paper是2001年CVPR上的文献：《A Bayesian Approach to Digital Matting》。</p><p>先看一下文献的抠图效果：</p><p><img src="https://s2.loli.net/2022/04/06/qWhacd1OmiK4lUG.png" alt="image-20220406172526482"></p><p>感觉很牛的样子，连头发都可以进行抠，然而其实这个算法的计算效率挺低的，到了后面你了解了这个算法，你就会知道速度有多么慢了。</p><h2 id="贝叶斯抠图算法"><a href="#贝叶斯抠图算法" class="headerlink" title="贝叶斯抠图算法"></a>贝叶斯抠图算法</h2><p>在融合方程中，已知的只有C，而F、B和α 都是未知的。于是可以从条件概率的角度去考虑这个问题，即给定C时，F、B和α的联合概率应为</p><p><img src="https://s2.loli.net/2022/04/06/5mjl6FsO1qacVwH.png" alt="image-20220406172606639"></p><p>其中第一个等号是根据贝叶斯公式得到的，第二个等号则是考虑F、B和α 是彼此独立的。</p><p>上式表明Matting问题可以被转化为已知待计算像素颜色C的情况下，如何估计它的F、B和α 的值以最大化后验概率P ( F , B , α ∣ C )的问题，即MAP问题。</p><p>上述等式中的右端项，需要通过采样统计的方式进行估计，而这种估计结果的准确性，很大程度上决定了算法的融合质量。具体来说，算法会采用一个连续滑动的窗口对邻域进行采样，窗口从未知区域和己知区域之间的两条边开始向内逐轮廓推进，计算过程也随之推进。下图左显示了Bayesian Matting方法的采样过程。</p><p>这篇paper中将采样窗口定义为一个以待计算点为中心，半径r的圆域。进行采样时，不但要对已知区域进行采样，同时为了在待计算像素周围保持一个连续的α分布，也要对之前计算出的邻域像素点进行采样。需要说明的是，采样窗口必须覆盖己知的前景和背景区域。这是因为用户提供的Trimap不能保证一定是足够精致的，换句话说，未知区域覆盖的像素有很多是纯粹的前景或背景，而非混合像素。如果采样半径内不能保证有己知区域内的像素采样，就有可能造成无法采样到前景或背景色。</p><p><img src="https://s2.loli.net/2022/04/06/5jIMbviGmdqtchA.png" alt="image-20220406173032872"></p><p>算法的核心假设是在前景和背景的交界区域附近，其各自的颜色分布在局部应该是基本一致的。算法的目标是通过上面给出的采样统计结果，在未知区域的每一个待计算点上重建它的前景和背景颜色概率分布，并根据这种分布恢复出它的前景色F，背景色B和α 值。</p><p>跟朴素贝叶斯法中处理情况一致，再利用对数似然L ( · ) ，所以有</p><p><img src="https://s2.loli.net/2022/04/06/85jStRD4fAvENCx.png" alt="image-20220406173048840"></p><p>使用对数似然的目的在于等价地把乘法转化成加法。因为P（c）是一个常数，所以在考虑最大化问题时可以将其忽略，上图右展示了一个应用这一规则求解最优F、B和α 的过程。我们就是要求解最优的参数：F、B、alpha值，使得上面的式子的概率最大化。</p><p>然而贝爷斯为了保证空间的连贯性，就以每个未知像素的N个邻域点，进行聚类，为了简化起见，paper先假设，前景色只有一类，背景色也只有一类，记住这个只是对于一个像素点的N个领域点而言。至于N的值大小，paper选择200，也就是说每个未知的像素选择最近的200个进行相关的高斯建模。也就是说这200个邻域点，聚类模型前景和背景都是单高斯模型，这样我们就可以求得着200个邻域点属于这个高斯模型的概率了。</p><h1 id="泊松图像融合"><a href="#泊松图像融合" class="headerlink" title="泊松图像融合"></a>泊松图像融合</h1><p>数学可以说是现代数字图像处理技术的一个重要基石，一些效果显著的同时也非常流行的图像处理技术中大量地借鉴和利用了经典数学理论中的一些著名的成果。尽管这些经典数学理论在其原有场景中的意义与其在图像处理技术中的应用二者之间的关系并没有那么明显！</p><p>泊松方程（Poisson Equation）在泊松图像编辑（Poisson Image Editing）以及泊松融合（Poisson Matting）中的应用就是一个典型的例子。</p><p>左图 这个人物是西莫恩·德尼·泊松（Siméon-Denis Poisson）是十九世纪法国著名数学家，曾经师从拉普拉斯和拉格朗日两位大师学习数学，数学中许多重要的概念（例如泊松分布、泊松积分、泊松方程 … …） 都以他的名字命名。</p><p><img src="https://s2.loli.net/2022/04/06/ixwpaLAP1SEehYl.png" alt="image-20220406173229490"></p><p><img src="https://s2.loli.net/2022/04/06/67GsA1xFqyuhdw5.png" alt="image-20220406173302144"></p><h2 id="泊松编辑"><a href="#泊松编辑" class="headerlink" title="泊松编辑"></a>泊松编辑</h2><p>经典物理中，引力场和电场都可以导出泊松方程，这里会设计到很多物理知识，下面重点说一下图像的泊松编辑</p><p>引力加速度场中的泊松公式中各物理量的关系如左图所示，下面将这其中的概念平行地转移到数字图像中。理解其中的对应关系是非常有意义的。</p><p><img src="https://s2.loli.net/2022/04/06/NU43pW1MtZTXgwk.png" alt="image-20220406173437141"></p><p>对于一组数字信号而言，它的能量在时域上主要是指它的振幅。而这种振幅对应到图像中，其实就是指各像素的灰度值。所以一幅图像的势能对应的就是原图像自身。对势能求梯度，可以得到相应的场。在图像处理中，可以利用哈密尔顿算子计算原图像的梯度结果，所以这里的场对应的就是图像梯度（注意这里有一个负号）。同理，利用拉普拉斯算子处理原图像，相应得到的就是密度图像。这些概念的对应关系如上图所示。</p><p>泊松方程之于图像处理的一个重要应用就是进行图像合成。图像合成是图像处理的一个基本问题，其通过将源图像中一个物体或者一个区域 （抠图）  嵌入到目标图像生成一个新的图像。</p><h2 id="Poisson-Image-Editing"><a href="#Poisson-Image-Editing" class="headerlink" title="Poisson Image Editing"></a>Poisson Image Editing</h2><p>这就引出来2004年Siggraph的经典paper：《Poisson Image Editing》，在图像融合领域，融合效果最牛逼的paper。开始这个算法前，我需要先讲解一个数学问题：</p><h3 id="散度计算"><a href="#散度计算" class="headerlink" title="散度计算"></a>散度计算</h3><p>现在假设一幅图像为3*3的单通道灰度图像</p><p><img src="https://s2.loli.net/2022/04/06/WdrBmY4N7bHLnCs.png" alt="image-20220406173605173"></p><p>我们假设每一点的像素值为V，V(1)表示像素点1的值，那么我们可以定义像素点5的散度的计算公式为：</p><p>div(5)=[V(2)+V(4)+V(6)+V(8)]-4*V(5)</p><p>说白了就是通过拉普拉斯卷积核，进行卷积，就可以求解散度了。</p><p><img src="https://s2.loli.net/2022/04/06/qeaQCTA9tGJinlW.png" alt="image-20220406173636538"></p><p>当然正规的过程应该是先求解像素点5的梯度值，然后在对梯度求导，这样就能得到散度，不过得到的结果其实就是上面的计算公式。</p><h3 id="泊松重建"><a href="#泊松重建" class="headerlink" title="泊松重建"></a>泊松重建</h3><p>OK，现在如果我给定一张图像，那么是不是可以利用拉普拉卷积核，求解每个点的散度</p><p>现在反过来，如果我给定每个像素点的散度，我要你求解每个像素点的值，要怎么求取。这便是泊松方程的灵魂了。为了更好的理解重建过程，我现在假设图像的大小是4*4的16个像素点图片，如下：</p><p><img src="https://s2.loli.net/2022/04/06/4gPEMtlNFZVGasY.png" alt="image-20220406173743691"></p><p>ok，假设我给你像素点6、7、10、11的散度值div(6)、div(7)、div(10)、div(11)，那么我们是不是可以列出如下4个方程：</p><p><img src="https://s2.loli.net/2022/04/06/D4iI93Px2gGrJNB.png" alt="image-20220406173801882"></p><p>这个时候，如果我们只有四个方程，可是里面有16个像素点，也就是说有16个未知数。因此单单靠上面的4个方程，就想把所有的像素值求解出来是不可能的，这样方程有无数多个解。因此我们需要添加约束方程，这个便是泊松重建方程的约束条件了。假设我们添加边界约束条件，也就是说如果我已经知道了上面那副图像最外围一圈的每个像素点的值u，这样我们就可以得到12个约束方程。即：</p><p><img src="https://s2.loli.net/2022/04/06/pHC7PVQl9XuLMS1.png" alt="image-20220406173814160"></p><p>上面有12个方程，外加给定的散度4个方程，这样我们有16个方程。这样就可以求解方程组了，这样就能实现通过散度+边界约束条件，实现图像重建。这个便是泊松方程的主要过程</p><p>因此泊松融合，说的再简单一点，就是求解方程组：</p><p>Ax=b</p><p>算法的整个过程在于求解系数稀疏矩阵A、及b。只要A、b求出来了，那么我们就可以求解方程组得到x，而x就是我们得到的融合结果的像素颜色值。</p><p>泊松图像编辑的主要思想是，根据原图像的梯度信息以及目标图像的边界信息，利用插值的方法重新构建出和成区域内的图像像素。如图上所示，其中u表示原图像中被合成的部分，V是u的梯度场，S是合并后的图像，Ω是合并后目标图像中被覆盖的区域，∂Ω是其边界。设合并后图像在Ω内的像素值由 f 表示，在外的像素值由 f*表示。<br>注意到图像合并的要求是使合并后的图像看上去尽量的平滑，没有明显的边界。所以，Ω内的梯度值应当尽可能的小。</p><p><img src="https://s2.loli.net/2022/04/06/FDBVCP14edR8XcQ.png" alt="image-20220406174048661"></p><p>最后展示一下这个算法的神器融合效果</p><p><img src="https://s2.loli.net/2022/04/06/3acmyLwOnCoBjSH.png" alt="image-20220406174058881"></p><h1 id="实时高分辨率背景抠图"><a href="#实时高分辨率背景抠图" class="headerlink" title="实时高分辨率背景抠图"></a>实时高分辨率背景抠图</h1><h2 id="Real-Time-High-Resolution-Background-Matting"><a href="#Real-Time-High-Resolution-Background-Matting" class="headerlink" title="Real-Time High-Resolution Background Matting"></a>Real-Time High-Resolution Background Matting</h2><p>CVPR 2021 最佳论文提名</p><p>为了使用户更方便地替换背景，研究人员陆续开发了一系列抠图方法。2020年 4 月份，华盛顿大学研究者提出了 background matting 方法，不在绿幕前拍摄也能完美转换视频背景，让整个世界都变成你的绿幕。但是，这项研究无法实现实时运行，只能以低帧率处理低分辨率下（512×512）的背景替换，有很多需要改进的地方。</p><p>八个月过去，2021这些研究者推出了 background matting 2.0 版本，并表示这是一种完全自动化、实时运行的高分辨率抠图方法，分别以 30fps 的帧率在 4k（3840×2160）和 60fps 的帧率在 HD（1920×1080）图像上产生非常好结果。</p><p>先来看一些效果展示场景：</p><p><img src="https://s2.loli.net/2022/04/06/NtYG4rifSpVDZaU.png" alt="image-20220406174229347"></p><p>非常自然流畅的背景替换。</p><h2 id="数据集"><a href="#数据集" class="headerlink" title="数据集"></a>数据集</h2><p>设计一个对高分辨率人物视频进行实时抠图的神经网络极具挑战性，特别是头发等细粒度细节特别重要的情况。1.0 版本只能以 8fps 的帧率实现 512×512 分辨率下的背景替换。若要在 4K 和 HD 这样的大分辨率图像上训练深度网络，则运行会非常慢，需要的内存也很大。此外，它还需要大量具备高质量前景蒙版（alpha matte）的图像以实现泛化，然而公开可用的数据集也很有限。</p><p>为此，他们创建了两个数据集 VideoMatte240K 和 PhotoMatte13K/85，二者均包含高分辨率前景蒙版以及利用色度键软件提取的前景层。研究者首先在这些包含显著多样化人体姿势的较大型前景蒙版数据集上训练网络以学习鲁棒性先验，然后在手动制作的公开可用数据集上继续训练以学习细粒度细节。</p><p><img src="https://s2.loli.net/2022/04/06/CBZqeaiH83hUnXx.png" alt="image-20220406174310054"></p><h2 id="模型架构图"><a href="#模型架构图" class="headerlink" title="模型架构图"></a>模型架构图</h2><p>此外，为了设计出能够实时处理高分辨率图像的网络，研究者观察发现图像中需要细粒度细化的区域相对很少。所以他们提出了一个 base 网络，用来预测低分辨率下的前景蒙版和前景层，并得到误差预测图（以确定哪些图像区域需要高分辨率细化）。然后 refinement 网络以低分辨率结果和原始图像作为输入，在选定区域生成高分辨率输出。</p><p><img src="https://s2.loli.net/2022/04/06/PEQMRon85Xax1sZ.png" alt="image-20220406174401155"></p><p>结果表明，Background Matting 2.0 版本在具有挑战性的真实视频和人物图像场景中取得了 SOTA 的实时背景抠图结果。研究者还将公布 VideoMatte240K 和 PhotoMatte85 数据集以及模型实现代码。</p><h2 id="实际使用"><a href="#实际使用" class="headerlink" title="实际使用"></a>实际使用</h2><p>研究人员将此方法应用到了 Zoom 视频会议和抠图这两种场景中。</p><p>在 Zoom 实现中，研究人员构建了拦截摄像头输入的 Zoom 插件，收集一张无人的背景图，然后执行实时视频抠图和合成，实际效果很好。</p><p>此外，研究人员对比了该方法和绿幕色度抠图的效果，发现在光照不均匀的环境下，该方法的效果胜过专为绿幕设计的方法，如下图所示：</p><p><img src="https://s2.loli.net/2022/04/06/NgLAiZ4zRcKyGof.png" alt="image-20220406174421639"></p>]]></content>
    
    
    <categories>
      
      <category>图像处理</category>
      
    </categories>
    
    
    <tags>
      
      <tag>图像处理</tag>
      
      <tag>抠图技术</tag>
      
    </tags>
    
  </entry>
  
  
  
  <entry>
    <title>蓝桥杯算法训练-Python实现</title>
    <link href="/2022/04/02/%E8%93%9D%E6%A1%A5%E6%9D%AF%E7%AE%97%E6%B3%95%E8%AE%AD%E7%BB%83-Python%E5%AE%9E%E7%8E%B0/"/>
    <url>/2022/04/02/%E8%93%9D%E6%A1%A5%E6%9D%AF%E7%AE%97%E6%B3%95%E8%AE%AD%E7%BB%83-Python%E5%AE%9E%E7%8E%B0/</url>
    
    <content type="html"><![CDATA[<h1 id="ALGO-1007-印章"><a href="#ALGO-1007-印章" class="headerlink" title="ALGO-1007 印章"></a>ALGO-1007 印章</h1><p><a href="http://lx.lanqiao.cn/problem.page?gpid=T3002">“蓝桥杯”练习系统 (lanqiao.cn)</a></p><p><strong>资源限制</strong></p><p>​        内存限制：256.0MB  C/C++时间限制：1.0s  Java时间限制：3.0s  Python时间限制：5.0s</p><p><strong>问题描述</strong></p><p>　　共有n种图案的印章，每种图案的出现概率相同。小A买了m张印章，求小A集齐n种印章的概率。</p><span id="more"></span><p><strong>输入格式</strong></p><p>　　一行两个正整数n和m</p><p><strong>输出格式</strong></p><p>　　一个实数P表示答案，保留4位小数。</p><p><strong>样例输入</strong></p><p>​        2 3</p><p><strong>样例输出</strong></p><p>​        0.7500</p><p><strong>数据规模和约定</strong></p><p>​        1≤n，m≤20</p><p>+++</p><p>此题采用动态规划（Dynamic Programming，DP）的方法求解，动态规划的三要素：最优子结构、边界和状态转移函数。</p><p>边界    问题最小子子集的解（初始范围）<br>最优子结构    每个阶段的最优状态可以从之前某个阶段的某个或某些状态直接得到<br>状态转移函数    从一个阶段向另一个阶段过度的具体形式,描述的是两个相邻子问题之间的关系(递推式)<br>对于本题，</p><figure class="highlight python"><table><tr><td class="gutter"><div class="code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><pre><code class="hljs python"><br></code></pre></td></tr></table></figure><figure class="highlight"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs"><br></code></pre></td></tr></table></figure>]]></content>
    
    
    <categories>
      
      <category>蓝桥杯</category>
      
    </categories>
    
    
    <tags>
      
      <tag>python</tag>
      
      <tag>蓝桥杯</tag>
      
      <tag>算法</tag>
      
    </tags>
    
  </entry>
  
  
  
  <entry>
    <title>深度学习，一种数据重于算法的思维转换</title>
    <link href="/2022/02/10/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%EF%BC%8C%E4%B8%80%E7%A7%8D%E6%95%B0%E6%8D%AE%E9%87%8D%E4%BA%8E%E7%AE%97%E6%B3%95%E7%9A%84%E6%80%9D%E7%BB%B4%E8%BD%AC%E6%8D%A2/"/>
    <url>/2022/02/10/%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%EF%BC%8C%E4%B8%80%E7%A7%8D%E6%95%B0%E6%8D%AE%E9%87%8D%E4%BA%8E%E7%AE%97%E6%B3%95%E7%9A%84%E6%80%9D%E7%BB%B4%E8%BD%AC%E6%8D%A2/</url>
    
    <content type="html"><![CDATA[<h1 id="深度学习所处的知识象限"><a href="#深度学习所处的知识象限" class="headerlink" title="深度学习所处的知识象限"></a>深度学习所处的知识象限</h1><p>深度学习：对于可统计的、但不可推理的（即象限Ⅲ），可通过神经网络这种特定的机器学习方法，达到性能提升的目的 </p><span id="more"></span><p><img src="https://s2.loli.net/2022/02/10/cJs9AlViDrGe7f2.png" alt="image-20220210123457396"></p><p>深度学习在本质上，就是层数非常多的人工神经网络，深度学习属于统计学习的范畴，统计机器学习的对象，其实就是数据。</p><p>简单来说，深度学习就是一种包含多个隐含层（层数越多即为越深）的多层感知机，深度学习将“特征提取”和“分类”合二为一，即达成所谓的端到端。</p><h1 id="深度学习的感性认知"><a href="#深度学习的感性认知" class="headerlink" title="深度学习的感性认知"></a>深度学习的感性认知</h1><p>把初恋期当作输入，磨合期当中调参，稳定期当作输出</p><p>书画琴棋诗酒花，<br>当年件件不离他。<br>而今七事都更变，<br>柴米油盐酱醋茶。</p><p>这首诗说的是在过日子的洗礼中，各种生活琐事的变迁，恋爱是过日子的一部分，双方需要不断磨合。</p><p><img src="https://s2.loli.net/2022/02/10/7pdxrOg61la9Rej.png" alt="image-20220210123914573"></p><p>调参：磨合。磨合中的权重取舍，就相当于深度学习中隐含层的参数调整</p><h1 id="深度学习发展简史"><a href="#深度学习发展简史" class="headerlink" title="深度学习发展简史"></a>深度学习发展简史</h1><p>无法承受参数之重的全连接前馈网络</p><p><img src="https://s2.loli.net/2022/02/10/Egz8eV74DRivfxp.png" alt="image-20220210124635185"></p><p>1968年，大卫·休伯尔在实验中发现两个有趣的现象</p><p><img src="https://s2.loli.net/2022/02/10/XFf2gKbs3liJBtw.png" alt="image-20220210124829159"></p><ol><li><p>神经元局部感知</p></li><li><p>动物大脑皮层是分级、分层处理信息的</p></li></ol><p><img src="https://s2.loli.net/2022/02/10/5ETxOhvDRzSJbsZ.png" alt="image-20220210124937424"></p><p>它对人工智能的启发意义在于：</p><ol><li>不必考虑使用神经元的”全连接“模式</li><li>神经网络拟合的复杂函数可分级、分层次来完成</li></ol><p>1980年，日本学者福岛邦彦：神经认知机，是一个使用无监督学习训练的神经网络模型，也是卷积神经网络的雏形</p><p><img src="https://s2.loli.net/2022/02/10/YhHbS2qk9TzE5aO.png" alt="image-20220210125503603"></p><p>1989年，Yann LeCun：利用BP算法重大改进 <strong>卷积神经网络</strong></p><p>LeCun把自己研究的网络命名为LeNet，主要用于字符识别</p><p><img src="https://s2.loli.net/2022/02/10/3BHrpi7hVOIaqQL.png" alt="image-20220210130039836"></p><p>20世纪90年代，俄罗斯统计学家V.Vapnik提出支持向量机（SVM）</p><p>2006年，深度学习的开山之作</p><p><img src="https://s2.loli.net/2022/02/10/lgWRF8mASG2unYE.png" alt="image-20220210130338057"></p><p>两个重要结论：</p><ol><li>多层的神经网络具有优秀的特征学习能力，能够学习到数据更本质的特征</li><li>多层神经网络的初始化参数可通过逐层预训练获得</li></ol><h1 id="卷积神经网络"><a href="#卷积神经网络" class="headerlink" title="卷积神经网络"></a>卷积神经网络</h1><p>所谓卷积是指一个函数和另一个函数在某个维度上的“叠加累计”作用。</p><h2 id="深度学习”层“的内涵"><a href="#深度学习”层“的内涵" class="headerlink" title="深度学习”层“的内涵"></a>深度学习”层“的内涵</h2><p>深度学习中的所谓“层”：就是对数据实施某种加工的过程。我们可以把神经网络层理解为数据过滤器。数据从输入端进来，经过转换，以另一种更有用的模式出去，这个过程叫做数据蒸馏（data distillation）</p><p><img src="https://s2.loli.net/2022/02/10/PrZRFtvY7IKQq8z.png" alt="将复杂高维数据展平的隐喻"></p><h2 id="图像处理中的卷积"><a href="#图像处理中的卷积" class="headerlink" title="图像处理中的卷积"></a>图像处理中的卷积</h2><p>计算机看到的是数字矩阵</p><p><img src="https://s2.loli.net/2022/02/10/KM8CURYFEp5AHoJ.png" alt="image-20220210134419017"></p><h2 id="卷积运算"><a href="#卷积运算" class="headerlink" title="卷积运算"></a>卷积运算</h2><h3 id="1D卷积运算"><a href="#1D卷积运算" class="headerlink" title="1D卷积运算"></a>1D卷积运算</h3><p><img src="https://s2.loli.net/2022/02/10/WBQ5USJRwZ4lk2O.png" alt="image-20220210134655334"></p><h3 id="二维图像数据的卷积"><a href="#二维图像数据的卷积" class="headerlink" title="二维图像数据的卷积"></a>二维图像数据的卷积</h3><p><img src="https://s2.loli.net/2022/02/10/5aGm46kh9Q8WYUt.png" alt="image-20220210134735340"></p><h3 id="3D卷积运算"><a href="#3D卷积运算" class="headerlink" title="3D卷积运算"></a>3D卷积运算</h3><p><img src="https://s2.loli.net/2022/02/10/UitqQzdc2obfj6Y.png" alt="image-20220210134808763"></p><h2 id="卷积在传统图像处理中的应用"><a href="#卷积在传统图像处理中的应用" class="headerlink" title="卷积在传统图像处理中的应用"></a>卷积在传统图像处理中的应用</h2><p><img src="https://s2.loli.net/2022/02/10/8FfhXi5YI249ycp.png" alt="image-20220210134842290"></p><h2 id="用python实现对图像的卷积-滤波"><a href="#用python实现对图像的卷积-滤波" class="headerlink" title="用python实现对图像的卷积(滤波)"></a>用python实现对图像的卷积(滤波)</h2><figure class="highlight python"><table><tr><td class="gutter"><div class="code-wrapper"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></div></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt<br><span class="hljs-keyword">import</span> pylab<br><span class="hljs-keyword">import</span> cv2<br><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np<br><br>img = plt.imread(<span class="hljs-string">&quot;dog.jpg&quot;</span>)                        <span class="hljs-comment">#在这里读取图片</span><br><br>plt.imshow(img)                                     <span class="hljs-comment">#显示读取的图片</span><br>pylab.show()<br><br>fil = np.array([[ -<span class="hljs-number">1</span>,-<span class="hljs-number">1</span>, <span class="hljs-number">0</span>],                        <span class="hljs-comment">#这个是设置的滤波，也就是卷积核</span><br>                [ -<span class="hljs-number">1</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>],<br>                [  <span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">1</span>]])<br><br>res = cv2.filter2D(img,-<span class="hljs-number">1</span>,fil)                      <span class="hljs-comment">#使用opencv的卷积函数</span><br><br>plt.imshow(res)                                     <span class="hljs-comment">#显示卷积后的图片</span><br><span class="hljs-comment"># plt.imsave(&quot;dog.jpg&quot;,res)</span><br>pylab.show()<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/10/IwZ8rRF9DPNVsSh.png" alt="image-20220210144934290"></p><h1 id="卷积神经网络的结构"><a href="#卷积神经网络的结构" class="headerlink" title="卷积神经网络的结构"></a>卷积神经网络的结构</h1><p><img src="https://s2.loli.net/2022/02/10/7zQn1ati4S6M59L.png" alt="image-20220210150601321"></p><p><img src="https://s2.loli.net/2022/02/10/y7B39FzRVDncSJP.png" alt="image-20220210150540452"></p><h2 id="卷积层"><a href="#卷积层" class="headerlink" title="卷积层"></a>卷积层</h2><p><strong>卷积的目的：作为特征提取器</strong></p><p><strong>用卷积来代替全连接</strong></p><p>卷积层是构建卷积神经网络的<strong>核心层</strong>，它产生了网络中大部分的<strong>计算量</strong>。注意是计算量而不是参数量。</p><p><strong>卷积层的作用：</strong></p><ol><li><p><strong>滤波器的作用或者说是卷积的作用</strong>。卷积层的参数是有一些可学习的滤波器集合构成的。每个滤波器在空间上（宽度和高度）都比较小，<strong>但是深度和输入数据一致</strong>。直观地来说，网络会让滤波器学习到当它看到某些类型的视觉特征时就激活，具体的视觉特征可能是某些方位上的边界，或者在第一层上某些颜色的斑点，甚至可以是网络更高层上的蜂巢状或者车轮状图案。</p></li><li><p><strong>可以被看做是神经元的一个输出</strong>。神经元只观察输入数据中的一小部分，并且和空间上左右两边的所有神经元共享参数（因为这些数字都是使用同一个滤波器得到的结果）。</p></li><li><p><strong>降低参数的数量</strong>。这个由于卷积具有“权值共享”这样的特性，可以降低参数数量，达到降低计算开销，防止由于参数过多而造成过拟合。</p></li></ol><p><strong>感受野（重点理解）:</strong></p><p>在处理图像这样的高维度输入时，让每个神经元都与前一层中的所有神经元进行全连接是不现实的。相反，我们让每个神经元只与输入数据的一个局部区域连接。<strong>该连接的空间大小叫做神经元的感受野</strong>（receptive field），它的尺寸是一个超参数（其实就是滤波器的空间尺寸）。<strong>在深度方向上，这个连接的大小总是和输入量的深度相等</strong>。需要再次强调的是，我们对待空间维度（宽和高）与深度维度是不同的：连接在空间（宽高）上是局部的，但是在深度上总是和输入数据的深度一致，这一点会在下面举例具体说明。</p><p><img src="https://s2.loli.net/2022/02/10/cYusIAJdDnwXK3B.jpg" alt="preview"></p><blockquote><p>在图 2 中展现的卷积神经网络的一部分，其中的红色为输入数据，假设输入数据体尺寸为[32x32x3]（比如CIFAR-10的RGB图像），如果感受野（或滤波器尺寸）是5x5，那么卷积层中的每个神经元会有输入数据体中[5x5x3]区域的权重，共5x5x3=75个权重（还要加一个偏差参数）。注意这个连接在深度维度上的大小必须为3，和输入数据体的深度一致。其中还有一点需要注意，对应一个感受野有75个权重，这75个权重是通过学习进行更新的，所以很大程度上这些权值之间是不相等（也就对于同一个卷积核，它对于与它连接的输入的每一层的权重都是独特的，不是同样的权重重复输入层层数那么多次就可以的）。在这里相当于前面的每一个层对应一个传统意义上的卷积模板，每一层与自己卷积模板做完卷积之后，再将各个层的结果加起来，再加上偏置，注意是<strong>一个偏置</strong>，无论输入输入数据是多少层，一个卷积核就对应一个偏置。</p></blockquote><h2 id="激活层"><a href="#激活层" class="headerlink" title="激活层"></a>激活层</h2><p><strong>激活层：非线性变换  –&gt;  提升神经网络的表达能力</strong></p><p><img src="https://s2.loli.net/2022/02/10/5pKjbLNDvmsURGt.png" alt="image-20220210152721404"></p><h2 id="池化层"><a href="#池化层" class="headerlink" title="池化层"></a>池化层</h2><p>通常在连续的卷积层之间会周期性地插入一个池化层。它的作用是逐渐降低数据体的空间尺寸，这样的话就能减少网络中参数的数量，使得计算资源耗费变少，也能有效控制过拟合。</p><p><img src="https://s2.loli.net/2022/02/10/PLbK8Z9wxiTDFMa.png" alt="image-20220210152926415"></p><p>池化带来的好处：平移不变性（Invariance）</p><h2 id="全连接层"><a href="#全连接层" class="headerlink" title="全连接层"></a>全连接层</h2><p><strong>全连接层:为分类服务</strong></p><p><img src="https://s2.loli.net/2022/02/10/twHBNQMfdJvqiZ6.png" alt="image-20220210153059331"></p><p>CNN的反向传播（BP）过程：</p><p><img src="https://s2.loli.net/2022/02/10/bcOrBU45CjwuyE1.png" alt="image-20220210153306379"></p><h1 id="神经网络的过拟合"><a href="#神经网络的过拟合" class="headerlink" title="神经网络的过拟合"></a>神经网络的过拟合</h1><p>过拟合是指，模型过于表征训练数据，导致在其他数据集上表现下降</p><p><img src="https://s2.loli.net/2022/02/10/Mzk4apBdG87nfJv.png" alt="image-20220210153403043"></p><p><img src="https://s2.loli.net/2022/02/10/IYjfBEcT63iNp52.png" alt="image-20220210153458273"></p><h1 id="基于卷积神经网络的手写数字识别"><a href="#基于卷积神经网络的手写数字识别" class="headerlink" title="基于卷积神经网络的手写数字识别"></a>基于卷积神经网络的手写数字识别</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment">#!/usr/bin/env python3</span><br><span class="hljs-comment"># -*- coding: utf-8 -*-</span><br><span class="hljs-string">&quot;&quot;&quot;</span><br><span class="hljs-string">Created on Tue May 12 12:56:10 2020</span><br><span class="hljs-string">参考代码：https://www.tensorflow.org/tutorials/quickstart/advanced</span><br><span class="hljs-string">&quot;&quot;&quot;</span><br><span class="hljs-comment"># （1）读入数据</span><br><span class="hljs-keyword">import</span> os<br><span class="hljs-keyword">import</span> tensorflow <span class="hljs-keyword">as</span> tf<br><span class="hljs-keyword">import</span> keras <span class="hljs-keyword">as</span> K<br><span class="hljs-comment"># mnist = tf.keras.datasets.mnist</span><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DataSource</span>():</span><br>    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span><br>        <span class="hljs-comment"># mnist数据集存储的位置，如何不存在将自动下载</span><br>        data_path = os.path.abspath(os.path.dirname(__file__)) + <span class="hljs-string">&#x27;/data/mnist.npz&#x27;</span><br>        <span class="hljs-comment"># (x_train, y_train), (x_test, y_test) = datasets.mnist.load_data(path=data_path)</span><br>        (x_train, y_train), (x_test, y_test) = K.datasets.mnist.load_data()<br>        <span class="hljs-comment"># 6万张训练图片，1万张测试图片</span><br>        <span class="hljs-comment">#        train_images = train_images.reshape((60000, 28, 28, 1))</span><br>        <span class="hljs-comment">#        test_images = test_images.reshape((10000, 28, 28, 1))</span><br>        x_train = x_train[..., tf.newaxis]<br>        x_test = x_test[..., tf.newaxis]<br>        <span class="hljs-comment"># 像素值映射到 0 - 1 之间</span><br>        x_train, x_test = x_train / <span class="hljs-number">255.0</span>, x_test / <span class="hljs-number">255.0</span><br><br>        self.train_images, self.train_labels = x_train, y_train<br>        self.test_images, self.test_labels = x_test, y_test<br><br>data = DataSource()<br><br><span class="hljs-comment"># (2)搭建模型</span><br><span class="hljs-keyword">import</span> tensorflow <span class="hljs-keyword">as</span> tf<br><span class="hljs-comment"># from tensorflow.keras import datasets, layers, models</span><br><span class="hljs-keyword">from</span> tensorflow.python.keras <span class="hljs-keyword">import</span> layers, models<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CNN</span>():</span><br>    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span><br>        model = models.Sequential()<br>        <span class="hljs-comment"># 第1层卷积，卷积核大小为3*3，32个，28*28为待训练图片的大小</span><br>        model.add(layers.Conv2D(<span class="hljs-number">32</span>, (<span class="hljs-number">3</span>, <span class="hljs-number">3</span>), activation=<span class="hljs-string">&#x27;relu&#x27;</span>, input_shape=(<span class="hljs-number">28</span>, <span class="hljs-number">28</span>, <span class="hljs-number">1</span>)))<br>        model.add(layers.MaxPooling2D((<span class="hljs-number">2</span>, <span class="hljs-number">2</span>)))<br>        <span class="hljs-comment"># 第2层卷积，卷积核大小为3*3，64个</span><br>        model.add(layers.Conv2D(<span class="hljs-number">64</span>, (<span class="hljs-number">3</span>, <span class="hljs-number">3</span>), activation=<span class="hljs-string">&#x27;relu&#x27;</span>))<br>        model.add(layers.MaxPooling2D((<span class="hljs-number">2</span>, <span class="hljs-number">2</span>)))<br>        <span class="hljs-comment"># 第3层卷积，卷积核大小为3*3，64个 </span><br>        model.add(layers.Conv2D(<span class="hljs-number">64</span>, (<span class="hljs-number">3</span>, <span class="hljs-number">3</span>), activation=<span class="hljs-string">&#x27;relu&#x27;</span>))<br>        <span class="hljs-comment"># 增加一个平坦层，拉平数据</span><br>        model.add(layers.Flatten())<br>        model.add(layers.Dense(<span class="hljs-number">64</span>, activation=<span class="hljs-string">&#x27;relu&#x27;</span>))<br>        model.add(layers.Dense(<span class="hljs-number">10</span>, activation=<span class="hljs-string">&#x27;softmax&#x27;</span>))<br><br>        model.summary()<br><br>        self.model = model<br><br>cnn = CNN()<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/10/Dmc2pVGOszq16Ia.png" alt="image-20220210155057781"></p><p><img src="https://s2.loli.net/2022/02/10/7O9tEoj3BNPqY61.png" alt="image-20220210155148881"></p><h1 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h1><p>人工智能极简入门-张玉宏 第七章</p><p><a href="https://www.cnblogs.com/Liu-xiang/p/10259861.html">图像处理中滤波器(卷积核) - Liu_xiang - 博客园 (cnblogs.com)</a></p><p><a href="https://www.cnblogs.com/youmuchen/p/6724780.html">用python实现对图像的卷积(滤波) - swuxyj - 博客园 (cnblogs.com)</a></p><p><a href="https://zhuanlan.zhihu.com/p/47184529">卷积神经网络（CNN）详解 - 知乎 (zhihu.com)</a></p>]]></content>
    
    
    <categories>
      
      <category>人工智能</category>
      
    </categories>
    
    
    <tags>
      
      <tag>人工智能</tag>
      
      <tag>机器学习</tag>
      
      <tag>深度学习</tag>
      
    </tags>
    
  </entry>
  
  
  
  <entry>
    <title>蓝桥杯基础练习python实现</title>
    <link href="/2022/02/09/%E8%93%9D%E6%A1%A5%E6%9D%AF/%E8%93%9D%E6%A1%A5%E6%9D%AF%E5%9F%BA%E7%A1%80%E7%BB%83%E4%B9%A0-python%E5%AE%9E%E7%8E%B0/"/>
    <url>/2022/02/09/%E8%93%9D%E6%A1%A5%E6%9D%AF/%E8%93%9D%E6%A1%A5%E6%9D%AF%E5%9F%BA%E7%A1%80%E7%BB%83%E4%B9%A0-python%E5%AE%9E%E7%8E%B0/</url>
    
    <content type="html"><![CDATA[<h1 id="BASIC-01-A-B问题"><a href="#BASIC-01-A-B问题" class="headerlink" title="BASIC-01 A+B问题"></a>BASIC-01 A+B问题</h1><figure class="highlight python"><table><tr><td class="gutter"><div class="code-wrapper"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></div></td><td class="code"><pre><code class="hljs python">a, b = <span class="hljs-built_in">input</span>().split(<span class="hljs-string">&quot; &quot;</span>)<br><span class="hljs-built_in">print</span>(<span class="hljs-built_in">int</span>(a)+<span class="hljs-built_in">int</span>(b))<br></code></pre></td></tr></table></figure><h1 id="BASIC-13-数列排序"><a href="#BASIC-13-数列排序" class="headerlink" title="BASIC-13 数列排序"></a>BASIC-13 数列排序</h1><figure class="highlight excel"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><code class="hljs excel">问题描述<br><br>　　给定一个长度为<span class="hljs-built_in">n</span>的数列，将这个数列按从小到大的顺序排列。<span class="hljs-number">1</span>&lt;=<span class="hljs-built_in">n</span>&lt;=<span class="hljs-number">200</span><br><br>输入格式<br><br>　　第一行为一个整数<span class="hljs-built_in">n</span>。<br>　　第二行包含<span class="hljs-built_in">n</span>个整数，为待排序的数，每个整数的绝对值小于<span class="hljs-number">10000</span>。<br><br>输出格式<br><br>　　输出一行，按从小到大的顺序输出排序后的数列。<br><br>样例输入<br><br><span class="hljs-number">5</span><br><span class="hljs-number">8</span> <span class="hljs-number">3</span> <span class="hljs-number">6</span> <span class="hljs-number">4</span> <span class="hljs-number">9</span><br><br>样例输出<br><br><span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">6</span> <span class="hljs-number">8</span> <span class="hljs-number">9</span><br></code></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs python">n = <span class="hljs-built_in">int</span>(<span class="hljs-built_in">input</span>())<br>s = <span class="hljs-built_in">sorted</span>(<span class="hljs-built_in">list</span>(<span class="hljs-built_in">map</span>(<span class="hljs-built_in">int</span>, <span class="hljs-built_in">input</span>().split())))<br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> s:<br>    <span class="hljs-built_in">print</span>(i, <span class="hljs-string">&#x27; &#x27;</span>, end=<span class="hljs-string">&quot;&quot;</span>)<br></code></pre></td></tr></table></figure><h1 id="BASIC-12-十六进制转八进制"><a href="#BASIC-12-十六进制转八进制" class="headerlink" title="BASIC-12  十六进制转八进制"></a>BASIC-12  十六进制转八进制</h1><p><strong>问题描述</strong><br>　　给定n个十六进制正整数，输出它们对应的八进制数。</p><p><strong>输入格式</strong><br>　　输入的第一行为一个正整数n （1&lt;=n&lt;=10）。<br>　　接下来n行，每行一个由0<del>9、大写字母A</del>F组成的字符串，表示要转换的十六进制正整数，每个十六进制数长度不超过100000。</p><p><strong>输出格式</strong><br>　　输出n行，每行为输入对应的八进制正整数。</p><p>　　<strong>【注意</strong>】<br>　　输入的十六进制数不会有前导0，比如012A。<br>　　输出的八进制数也不能有前导0。</p><p><strong>样例输入</strong><br>　　2<br>　　39<br>　　123ABC</p><p><strong>样例输出</strong><br>　　71<br>　　4435274</p><p><strong>提示</strong><br>　　先将十六进制数转换成某进制数，再由某进制数转换成八进制。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs python">n = <span class="hljs-built_in">int</span>(<span class="hljs-built_in">input</span>())<br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(n):<br>    a = <span class="hljs-built_in">input</span>()<br>    result = <span class="hljs-built_in">int</span>(a, base=<span class="hljs-number">16</span>)  <span class="hljs-comment"># int 十六进制转换为十进制</span><br>    <span class="hljs-built_in">print</span>(<span class="hljs-built_in">oct</span>(result)[<span class="hljs-number">2</span>:])  <span class="hljs-comment"># oct 十进制转换为八进制</span><br></code></pre></td></tr></table></figure><h1 id="BASIC-11-十六进制转十进制"><a href="#BASIC-11-十六进制转十进制" class="headerlink" title="BASIC-11 十六进制转十进制"></a>BASIC-11 十六进制转十进制</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs python">a = <span class="hljs-built_in">input</span>()<br>result = <span class="hljs-built_in">int</span>(a, base=<span class="hljs-number">16</span>)<br><span class="hljs-built_in">print</span>(result)<br></code></pre></td></tr></table></figure><h1 id="BASIC-10-十进制转十六进制"><a href="#BASIC-10-十进制转十六进制" class="headerlink" title="BASIC-10 十进制转十六进制"></a>BASIC-10 十进制转十六进制</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs python">a = <span class="hljs-built_in">int</span>(<span class="hljs-built_in">input</span>())<br>result = <span class="hljs-built_in">hex</span>(a)[<span class="hljs-number">2</span>:]<br><span class="hljs-built_in">print</span>(result.upper())<br></code></pre></td></tr></table></figure><h1 id="BASIC-9-特殊回文数"><a href="#BASIC-9-特殊回文数" class="headerlink" title="BASIC-9 特殊回文数"></a>BASIC-9 特殊回文数</h1><figure class="highlight excel"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><code class="hljs excel">问题描述<br><br>　　<span class="hljs-number">123321</span>是一个非常特殊的数，它从左边读和从右边读是一样的。<br>　　输入一个正整数<span class="hljs-built_in">n</span>， 编程求所有这样的五位和六位十进制数，满足各位数字之和等于<span class="hljs-built_in">n</span> 。<br><br>输入格式<br><br>　　输入一行，包含一个正整数<span class="hljs-built_in">n</span>。<br><br>输出格式<br><br>　　按从小到大的顺序输出满足条件的整数，每个整数占一行。<br><br>样例输入<br><br><span class="hljs-number">52</span><br><br>样例输出<br><br><span class="hljs-number">899998</span><br><span class="hljs-number">989989</span><br><span class="hljs-number">998899</span><br><br>数据规模和约定<br><br>　　<span class="hljs-number">1</span>&lt;=<span class="hljs-built_in">n</span>&lt;=<span class="hljs-number">54</span>。<br></code></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs python">n = <span class="hljs-built_in">int</span>(<span class="hljs-built_in">input</span>())<br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">10000</span>, <span class="hljs-number">1000000</span>):  <span class="hljs-comment"># 1000000</span><br>    i = <span class="hljs-built_in">str</span>(i)<br>    <span class="hljs-keyword">if</span> i[::-<span class="hljs-number">1</span>] == i <span class="hljs-keyword">and</span> <span class="hljs-built_in">sum</span>(<span class="hljs-built_in">int</span>(j) <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> i) == n:<br>        <span class="hljs-built_in">print</span>(i)<br></code></pre></td></tr></table></figure><p>字符串逆置 <code>str[::-1]</code></p><p>求一个整数各位之和 <code>sum(int(i) for i in str(num))</code></p><p>注意 <code>n=input()</code>输入的是字符串类型，要转换成<code>int</code></p><h1 id="BASIC-8-回文数"><a href="#BASIC-8-回文数" class="headerlink" title="BASIC-8 回文数"></a>BASIC-8 回文数</h1><p>问题描述</p><p>　　1221是一个非常特殊的数，它从左边读和从右边读是一样的，编程求所有这样的四位十进制数。</p><p>输出格式</p><p>　　按从小到大的顺序输出满足条件的四位十进制数。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1000</span>, <span class="hljs-number">10000</span>):<br>    i = <span class="hljs-built_in">str</span>(i)<br>    <span class="hljs-keyword">if</span> i[::-<span class="hljs-number">1</span>] == i:<br>        <span class="hljs-built_in">print</span>(i)<br></code></pre></td></tr></table></figure><h1 id="BASIC-7-特殊的数字"><a href="#BASIC-7-特殊的数字" class="headerlink" title="BASIC-7 特殊的数字"></a>BASIC-7 特殊的数字</h1><p>问题描述</p><p>　　153是一个非常特殊的数，它等于它的每位数字的立方和，即153=1<em>1</em>1+5<em>5</em>5+3<em>3</em>3。编程求所有满足这种条件的三位十进制数。</p><p>输出格式</p><p>　　按从小到大的顺序输出满足条件的三位十进制数，每个数占一行。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">for</span> num <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">100</span>, <span class="hljs-number">1000</span>):<br>    p_num = <span class="hljs-built_in">pow</span>(<span class="hljs-built_in">int</span>(<span class="hljs-built_in">str</span>(num)[:<span class="hljs-number">1</span>]), <span class="hljs-number">3</span>) + <span class="hljs-built_in">pow</span>(<span class="hljs-built_in">int</span>(<span class="hljs-built_in">str</span>(num)[<span class="hljs-number">1</span>:<span class="hljs-number">2</span>]), <span class="hljs-number">3</span>) + <span class="hljs-built_in">pow</span>(<span class="hljs-built_in">int</span>(<span class="hljs-built_in">str</span>(num)[<span class="hljs-number">2</span>:<span class="hljs-number">3</span>]), <span class="hljs-number">3</span>)<br>    <span class="hljs-keyword">if</span> num == <span class="hljs-built_in">int</span>(p_num):<br>        <span class="hljs-built_in">print</span>(num)<br></code></pre></td></tr></table></figure><h1 id="BASIC-6-杨辉三角形"><a href="#BASIC-6-杨辉三角形" class="headerlink" title="BASIC-6 杨辉三角形"></a>BASIC-6 杨辉三角形</h1><p><strong>问题描述</strong></p><p>杨辉三角形又称Pascal三角形，它的第i+1行是(a+b)i的展开式的系数。</p><p>它的一个重要性质是：三角形中的每个数字等于它两肩上的数字相加。</p><p>下面给出了杨辉三角形的前4行：</p><p>  1</p><p> 1 1</p><p> 1 2 1</p><p>1 3 3 1</p><p>给出n，输出它的前n行。</p><p><strong>输入格式</strong></p><p>输入包含一个数n。</p><p><strong>输出格式</strong></p><p>输出杨辉三角形的前n行。每一行从这一行的第一个数开始依次输出，中间使用一个空格分隔。请不要在前面输出多余的空格。</p><p><strong>样例输入</strong></p><p>4</p><p><strong>样例输出</strong></p><p>1<br>1 1<br>1 2 1<br>1 3 3 1</p><p><strong>数据规模与约定</strong></p><p>1 &lt;= n &lt;= 34。</p><p>首先初步创建一个n*n的二维列表矩阵，内容初步使用for循环填充，便于接下来的数据调整。根据杨辉三角基本性质，先将主对角线以上部分填充0，然后将第一列及主对角线填充为1，剩余部分根据性质计算得<code>pascallist[i][j] = pascallist[i - 1][j - 1] + pascallist[i - 1][j]</code>，即该数据等于对应左上方和正上方值之和。去零输出，当数据为零时，continue直接进入下一次循环，并按照题目格式输出矩阵。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs python">num = <span class="hljs-built_in">int</span>(<span class="hljs-built_in">input</span>())<br>pl = [[i <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(num)] <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(num)]<br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(num):<br>    <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(num):<br>        <span class="hljs-keyword">if</span> j &gt; i:<br>            pl[i][j] = <span class="hljs-number">0</span><br>        <span class="hljs-keyword">elif</span> i == j:<br>            pl[i][j] = <span class="hljs-number">1</span><br>        <span class="hljs-keyword">elif</span> j == <span class="hljs-number">0</span>:<br>            pl[i][j] = <span class="hljs-number">1</span><br>        <span class="hljs-keyword">else</span>:<br>            pl[i][j] = pl[i - <span class="hljs-number">1</span>][j - <span class="hljs-number">1</span>] + pl[i - <span class="hljs-number">1</span>][j]<br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(num):<br>    <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(num):<br>        <span class="hljs-keyword">if</span> pl[i][j] == <span class="hljs-number">0</span>:<br>            <span class="hljs-keyword">continue</span><br>        <span class="hljs-keyword">else</span>:<br>            <span class="hljs-built_in">print</span>(pl[i][j], end=<span class="hljs-string">&quot; &quot;</span>)<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;&quot;</span>)<br></code></pre></td></tr></table></figure><h1 id="BASIC-5-查找整数"><a href="#BASIC-5-查找整数" class="headerlink" title="BASIC-5 查找整数"></a>BASIC-5 查找整数</h1><p><strong>问题描述</strong></p><p>给出一个包含n个整数的数列，问整数a在数列中的第一次出现是第几个。</p><p><strong>输入格式</strong></p><p>第一行包含一个整数n。</p><p>第二行包含n个非负整数，为给定的数列，数列中的每个数都不大于10000。</p><p>第三行包含一个整数a，为待查找的数。</p><p><strong>输出格式</strong></p><p>如果a在数列中出现了，输出它第一次出现的位置(位置从1开始编号)，否则输出-1。</p><p><strong>样例输入</strong></p><p>6<br>1 9 4 8 3 9<br>9</p><p><strong>样例输出</strong></p><p>2</p><p><strong>数据规模与约定</strong></p><p>1 &lt;= n &lt;= 1000。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs python">n = <span class="hljs-built_in">int</span>(<span class="hljs-built_in">input</span>())<br>num = <span class="hljs-built_in">list</span>(<span class="hljs-built_in">input</span>().split(<span class="hljs-string">&quot; &quot;</span>))<br>a = <span class="hljs-built_in">int</span>(<span class="hljs-built_in">input</span>())<br>flag = <span class="hljs-number">0</span><br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(n):<br>    <span class="hljs-keyword">if</span> a == <span class="hljs-built_in">int</span>(num[i]):<br>        <span class="hljs-built_in">print</span>(i+<span class="hljs-number">1</span>)<br>        flag = <span class="hljs-number">1</span><br>        <span class="hljs-keyword">break</span><br><span class="hljs-keyword">if</span> flag == <span class="hljs-number">0</span>:<br>    <span class="hljs-built_in">print</span>(-<span class="hljs-number">1</span>)<br></code></pre></td></tr></table></figure><h1 id="BASIC-4-数列特征"><a href="#BASIC-4-数列特征" class="headerlink" title="BASIC-4 数列特征"></a>BASIC-4 数列特征</h1><p><strong>问题描述</strong></p><p>给出n个数，找出这n个数的最大值，最小值，和。</p><p><strong>输入格式</strong></p><p>第一行为整数n，表示数的个数。</p><p>第二行有n个数，为给定的n个数，每个数的绝对值都小于10000。</p><p><strong>输出格式</strong></p><p>输出三行，每行一个整数。第一行表示这些数中的最大值，第二行表示这些数中的最小值，第三行表示这些数的和。</p><p><strong>样例输入</strong></p><p>5<br>1 3 -2 4 5</p><p><strong>样例输出</strong></p><p>5<br>-2<br>11</p><p><strong>数据规模与约定</strong></p><p>1 &lt;= n &lt;= 10000。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs python">n = <span class="hljs-built_in">int</span>(<span class="hljs-built_in">input</span>())<br>num = <span class="hljs-built_in">list</span>(<span class="hljs-built_in">map</span>(<span class="hljs-built_in">int</span>, <span class="hljs-built_in">input</span>().split()))<br><span class="hljs-built_in">print</span>(<span class="hljs-built_in">max</span>(num))<br><span class="hljs-built_in">print</span>(<span class="hljs-built_in">min</span>(num))<br><span class="hljs-built_in">print</span>(<span class="hljs-built_in">sum</span>(num))<br></code></pre></td></tr></table></figure><h1 id="BASIC-3-字母图形"><a href="#BASIC-3-字母图形" class="headerlink" title="BASIC-3 字母图形"></a>BASIC-3 字母图形</h1><p><strong>问题描述</strong></p><p>利用字母可以组成一些美丽的图形，下面给出了一个例子：</p><p>ABCDEFG</p><p>BABCDEF</p><p>CBABCDE</p><p>DCBABCD</p><p>EDCBABC</p><p>这是一个5行7列的图形，请找出这个图形的规律，并输出一个n行m列的图形。</p><p><strong>输入格式</strong></p><p>输入一行，包含两个整数n和m，分别表示你要输出的图形的行数的列数。</p><p><strong>输出格式</strong></p><p>输出n行，每行m个字符，为你的图形。</p><p><strong>样例输入</strong></p><p>5 7</p><p><strong>样例输出</strong></p><p>ABCDEFG<br>BABCDEF<br>CBABCDE<br>DCBABCD<br>EDCBABC</p><p><strong>数据规模与约定</strong></p><p>1 &lt;= n, m &lt;= 26。</p><p>参考了<code>BASIC-6</code>杨辉三角形的解题方法</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs python">num = <span class="hljs-built_in">list</span>(<span class="hljs-built_in">map</span>(<span class="hljs-built_in">int</span>, <span class="hljs-built_in">input</span>().split()))<br>n, m = num<br>a = [[i <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(m)] <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(n)]<br>t = b =<span class="hljs-number">65</span><br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(n):<br>    <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(m):<br>        <span class="hljs-keyword">if</span> i == <span class="hljs-number">0</span>:<br>            a[i][j] = <span class="hljs-built_in">chr</span>(t)<br>            t = t + <span class="hljs-number">1</span><br>        <span class="hljs-keyword">elif</span> j == <span class="hljs-number">0</span>:<br>            b = b + <span class="hljs-number">1</span><br>            a[i][j] = <span class="hljs-built_in">chr</span>(b)<br>        <span class="hljs-keyword">else</span>:<br>            a[i][j] = a[i-<span class="hljs-number">1</span>][j-<span class="hljs-number">1</span>]<br><br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(n):<br>    <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(m):<br>        <span class="hljs-built_in">print</span>(a[i][j], end=<span class="hljs-string">&quot;&quot;</span>)<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;&quot;</span>)<br></code></pre></td></tr></table></figure><p>法二：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">try</span>:<br>    n, m = <span class="hljs-built_in">map</span>(<span class="hljs-built_in">int</span>, <span class="hljs-built_in">input</span>().split())<br>    letter = <span class="hljs-string">&#x27;ABCDEFGHIJKLMNOPQRSTUVWXYZ&#x27;</span><br>    x = letter[:m]<br>    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>, n+<span class="hljs-number">1</span>):<br>        <span class="hljs-built_in">print</span>(x)<br>        x = letter[i] + x[<span class="hljs-number">0</span>:-<span class="hljs-number">1</span>]<br><span class="hljs-keyword">except</span>:<br>    <span class="hljs-keyword">pass</span><br></code></pre></td></tr></table></figure><p> 注意：代码的except的设计，实际上是“当索引溢出了，程序还能正常退出”。否则会运行错误</p><p>法三：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs python">n, m = <span class="hljs-built_in">map</span>(<span class="hljs-built_in">int</span>, <span class="hljs-built_in">input</span>().split())<br>letter = <span class="hljs-string">&#x27;ABCDEFGHIJKLMNOPQRSTUVWXYZ&#x27;</span><br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(n):<br>    r = letter[<span class="hljs-number">1</span>:i+<span class="hljs-number">1</span>]<br>    f = letter[<span class="hljs-number">0</span>:m-i]<br>    s = r[::-<span class="hljs-number">1</span>] + f<br>    <span class="hljs-built_in">print</span>(s[<span class="hljs-number">0</span>:m])<br></code></pre></td></tr></table></figure><h1 id="BASAIC-2-01字串"><a href="#BASAIC-2-01字串" class="headerlink" title="BASAIC-2 01字串"></a>BASAIC-2 01字串</h1><p><strong>问题描述</strong></p><p>对于长度为5位的一个01串，每一位都可能是0或1，一共有32种可能。它们的前几个是：</p><p>00000</p><p>00001</p><p>00010</p><p>00011</p><p>00100</p><p>请按从小到大的顺序输出这32种01串。</p><p><strong>输入格式</strong></p><p>本试题没有输入。</p><p><strong>输出格式</strong></p><p>输出32行，按从小到大的顺序每行一个长度为5的01串。</p><p><strong>样例输出</strong></p><p>00000<br>00001<br>00010<br>00011</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs python">a = <span class="hljs-string">&quot;0&quot;</span><br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">32</span>):<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;%05d&quot;</span> % <span class="hljs-built_in">int</span>(a))<br>    a = <span class="hljs-built_in">bin</span>(<span class="hljs-built_in">int</span>(a, base=<span class="hljs-number">2</span>) + <span class="hljs-built_in">int</span>(<span class="hljs-string">&quot;1&quot;</span>, base=<span class="hljs-number">2</span>))[<span class="hljs-number">2</span>:]<br></code></pre></td></tr></table></figure><p>法二：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">32</span>):<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&#x27;&#123;:05b&#125;&#x27;</span>.<span class="hljs-built_in">format</span>(i))<br></code></pre></td></tr></table></figure><p><code>:b</code> 代表二进制</p><h1 id="BASIC-1-闰年判断"><a href="#BASIC-1-闰年判断" class="headerlink" title="BASIC-1 闰年判断"></a>BASIC-1 闰年判断</h1><p><strong>问题描述</strong></p><p>给定一个年份，判断这一年是不是闰年。</p><p>当以下情况之一满足时，这一年是闰年：</p><ol><li><p>年份是4的倍数而不是100的倍数；</p></li><li><p>年份是400的倍数。</p></li></ol><p>其他的年份都不是闰年。</p><p><strong>输入格式</strong></p><p>输入包含一个整数y，表示当前的年份。</p><p><strong>输出格式</strong></p><p>输出一行，如果给定的年份是闰年，则输出yes，否则输出no。</p><p><strong>样例输入</strong></p><p>2013</p><p><strong>样例输出</strong></p><p>no</p><p><strong>样例输入</strong></p><p>2016</p><p><strong>样例输出</strong></p><p>yes</p><p><strong>数据规模与约定</strong></p><p>1990 &lt;= y &lt;= 2050。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs python">year = <span class="hljs-built_in">int</span>(<span class="hljs-built_in">input</span>())<br><span class="hljs-keyword">if</span> (year % <span class="hljs-number">4</span> == <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> year % <span class="hljs-number">100</span> != <span class="hljs-number">0</span>) <span class="hljs-keyword">or</span> year % <span class="hljs-number">400</span> == <span class="hljs-number">0</span>:<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;yes&quot;</span>)<br><span class="hljs-keyword">else</span>:<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;no&quot;</span>)<br></code></pre></td></tr></table></figure><h1 id="BASIC-04-Fibonacci数列"><a href="#BASIC-04-Fibonacci数列" class="headerlink" title="BASIC-04 Fibonacci数列"></a>BASIC-04 Fibonacci数列</h1><p><strong>问题描述</strong></p><p>Fibonacci数列的递推公式为：Fn=Fn-1+Fn-2，其中F1=F2=1。</p><p>当n比较大时，Fn也非常大，现在我们想知道，Fn除以10007的余数是多少。</p><p><strong>输入格式</strong></p><p>输入包含一个整数n。</p><p><strong>输出格式</strong></p><p>输出一行，包含一个整数，表示Fn除以10007的余数。</p><p>说明：在本题中，答案是要求Fn除以10007的余数，因此我们只要能算出这个余数即可，而不需要先计算出Fn的准确值，再将计算的结果除以10007取余数，直接计算余数往往比先算出原数再取余简单。</p><p><strong>样例输入</strong></p><p>10</p><p><strong>样例输出</strong></p><p>55</p><p><strong>样例输入</strong></p><p>22</p><p><strong>样例输出</strong></p><p>7704</p><p><strong>数据规模与约定</strong></p><p>1 &lt;= n &lt;= 1,000,000。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs python">n = <span class="hljs-built_in">int</span>(<span class="hljs-built_in">input</span>())<br><span class="hljs-built_in">sum</span> = <span class="hljs-number">1</span><br>b = <span class="hljs-number">1</span><br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">3</span>, n+<span class="hljs-number">1</span>):<br>    t = <span class="hljs-built_in">sum</span><br>    <span class="hljs-built_in">sum</span> = (<span class="hljs-built_in">sum</span> + b) % <span class="hljs-number">10007</span><br>    b = t<br><span class="hljs-built_in">print</span>(<span class="hljs-built_in">sum</span>%<span class="hljs-number">10007</span>)<br></code></pre></td></tr></table></figure><p>法二：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs python">n = <span class="hljs-built_in">int</span>(<span class="hljs-built_in">input</span>())<br><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">fibo</span>(<span class="hljs-params">n</span>):</span><br>    a, b = <span class="hljs-number">1</span>, <span class="hljs-number">1</span><br>    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">2</span>, n+<span class="hljs-number">1</span>):<br>        a, b = b, (a+b)%<span class="hljs-number">10007</span><br>    <span class="hljs-keyword">return</span> a<br><span class="hljs-built_in">print</span>(fibo(n))<br></code></pre></td></tr></table></figure><h1 id="BASIC-03-圆的面积"><a href="#BASIC-03-圆的面积" class="headerlink" title="BASIC-03 圆的面积"></a>BASIC-03 圆的面积</h1><p><strong>问题描述</strong></p><p>给定圆的半径r，求圆的面积。</p><p><strong>输入格式</strong></p><p>输入包含一个整数r，表示圆的半径。</p><p><strong>输出格式</strong></p><p>输出一行，包含一个实数，四舍五入保留小数点后7位，表示圆的面积。</p><p>说明：在本题中，输入是一个整数，但是输出是一个实数。</p><p>对于实数输出的问题，请一定看清楚实数输出的要求，比如本题中要求保留小数点后7位，则你的程序必须<strong>严格的</strong>输出7位小数，输出过多或者过少的小数位数都是不行的，都会被认为错误。</p><p>实数输出的问题如果没有特别说明，舍入都是按四舍五入进行。</p><p><strong>样例输入</strong></p><p>4</p><p><strong>样例输出</strong></p><p>50.2654825</p><p><strong>数据规模与约定</strong></p><p>1 &lt;= r &lt;= 10000。</p><p><strong>提示</strong></p><p>本题对精度要求较高，请注意π的值应该取较精确的值。你可以使用常量来表示π，比如PI=3.14159265358979323，也可以使用数学公式来求π，比如PI=atan(1.0)*4。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> math<br><br>r = <span class="hljs-built_in">int</span>(<span class="hljs-built_in">input</span>())<br>s = math.pi * r * r<br><span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;%.7f&quot;</span> % s)<br></code></pre></td></tr></table></figure><h1 id="BASIC-02-序列求和"><a href="#BASIC-02-序列求和" class="headerlink" title="BASIC-02 序列求和"></a>BASIC-02 序列求和</h1><p><strong>资源限制</strong></p><p>时间限制：1.0s  内存限制：256.0MB</p><p><strong>问题描述</strong></p><p>求1+2+3+…+n的值。</p><p><strong>输入格式</strong></p><p>输入包括一个整数n。</p><p><strong>输出格式</strong></p><p>输出一行，包括一个整数，表示1+2+3+…+n的值。</p><p><strong>样例输入</strong></p><p>4</p><p><strong>样例输出</strong></p><p>10</p><p><strong>样例输入</strong></p><p>100</p><p><strong>样例输出</strong></p><p>5050</p><p><strong>数据规模与约定</strong></p><p>1 &lt;= n &lt;= 1,000,000,000。</p><p><strong>说明：请注意这里的数据规模。</strong></p><p>本题直接的想法是直接使用一个循环来累加，然而，当数据规模很大时，这种“暴力”的方法往往会导致超时。此时你需要想想其他方法。你可以试一试，如果使用1000000000作为你的程序的输入，你的程序是不是能在规定的上面规定的时限内运行出来。</p><p>本题另一个要值得注意的地方是答案的大小不在你的语言默认的整型(int)范围内，如果使用整型来保存结果，会导致结果错误。</p><p>如果你使用C++或C语言而且准备使用printf输出结果，则你的格式字符串应该写成%I64d以输出long long类型的整数。</p><p>下面的代码会运行超时：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs python">n = <span class="hljs-built_in">int</span>(<span class="hljs-built_in">input</span>())<br><span class="hljs-built_in">sum</span> = <span class="hljs-number">0</span><br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(n+<span class="hljs-number">1</span>):<br>    <span class="hljs-built_in">sum</span> = <span class="hljs-built_in">sum</span> + i<br><span class="hljs-built_in">print</span>(<span class="hljs-built_in">sum</span>)<br></code></pre></td></tr></table></figure><p>直接用求和公式：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python">n = <span class="hljs-built_in">int</span>(<span class="hljs-built_in">input</span>())<br><span class="hljs-built_in">print</span>(n*(n+<span class="hljs-number">1</span>)//<span class="hljs-number">2</span>)<br></code></pre></td></tr></table></figure><p>两个斜杠即双斜杠（//）表示地板除，即先做除法（/）</p>]]></content>
    
    
    <categories>
      
      <category>蓝桥杯</category>
      
    </categories>
    
    
    <tags>
      
      <tag>python</tag>
      
      <tag>蓝桥杯</tag>
      
    </tags>
    
  </entry>
  
  
  
  <entry>
    <title>机器学习四大门派</title>
    <link href="/2022/02/09/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E5%9B%9B%E5%A4%A7%E9%97%A8%E6%B4%BE/"/>
    <url>/2022/02/09/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E5%9B%9B%E5%A4%A7%E9%97%A8%E6%B4%BE/</url>
    
    <content type="html"><![CDATA[<h1 id="什么是学习？"><a href="#什么是学习？" class="headerlink" title="什么是学习？"></a>什么是学习？</h1><p>著名学者赫伯特·西蒙教授（Herbert Simon，1975年图灵奖获得者、1978年诺贝尔经济学奖获得者）曾对“学习”给了一个定义：“如果一个系统，能够通过执行某个过程，就此改进了它的性能，那么这个过程就是学习”。<br>大牛就是大牛，永远都是那么言简意赅，一针见血。从西蒙教授的观点可以看出，<strong>学习的核心目的，就是改善性能</strong>。</p><span id="more"></span><p>其实对于人而言，这个定义也是适用的。比如，我们现在正在学习“机器学习”的知识，其本质目的就是为了“提升”自己在机器学习上的认知水平。如果我们仅仅是低层次的重复性学习，而没有达到认知升级的目的，那么即使表面看起来非常勤奋，其实我们也仅仅是个“伪学习者”, 因为我们没有改善性能。</p><p>按照这个解释，那句著名的口号“好好学习，天天向上”，就会焕发新的含义:如果没有性 能上的“向上”，即使非常辛苦地“好好”，即使长时间地“天天”，都无法算作“学习”。</p><h1 id="什么是机器学习？"><a href="#什么是机器学习？" class="headerlink" title="什么是机器学习？"></a>什么是机器学习？</h1><p>赫伯特·西蒙认为<strong>Machine learning</strong> is the ability to “learn” (i.e., progressively <strong>improve performance</strong> on a specific task) <strong>with data</strong>, without being explicitly programmed</p><p>英雄所见略同。卡内基梅隆大学的Tom Mitchell教授，在他的名作《机器学习》一书中，也给出了更为具体（其实也很抽象）的定义：对于某类任务（Task，简称T）和某项性能评价准则（Performance，简称P），如果一个计算机程序在T上，以P作为性能的度量，随着很多经验（Experience，简称E）不断自我完善，那么我们称这个计算机程序在从经验E中学习了。</p><p>比如说，对于学习围棋的程序AlphaGo，它可以通过和自己下棋获取经验，那么它的任务T就是“参与围棋对弈”；它的性能P就是用“赢得比赛的百分比”来度量。“类似地，学生的任务T就是“上课看书写作业”；它的性能P就是用“期末成绩”来度量”</p><p><img src="https://s2.loli.net/2022/02/09/pT6vWbEA4teglMC.png" alt="image-20220209154808123"></p><p>在前面的文章中已提到，一般说来，人类的知识在两个维度上可分成四类，见上图。即从可统计与否上来看，可分为：是可统计的和不可统计的。从能否推理上看，可分为可推理的和不可推理的。</p><p>在横向方向上，对于可推理的，我们都可以通过机器学习的方法，最终可以完成这个推理。传统的机器学习方法，就是试图找到可举一反三的方法，向可推理但不可统计的象限进发（象限Ⅱ）。目前看来，这个象限的研究工作（即基于推理的机器学习）陷入了不温不火的境地，能不能峰回路转，还有待时间的检验。</p><p>而在纵向上，对于可统计的、但不可推理的（即象限Ⅲ），可通过神经网络这种特定的机器学习方法，以期望达到性能提升的目的。目前，基于深度学习的棋类博弈（阿尔法狗）、计算机视觉（猫狗识别）、自动驾驶等等，其实都是在这个象限做出了了不起的成就。<br>从图1可知，深度学习属于统计学习的范畴。用李航博士的话来说，统计机器学习的对象，其实就是数据[3]。这是因为，对于计算机系统而言，所有的“经验”都是以数据的形式存在的。作为学习的对象，数据的类型是多样的，可以是各种数字、文字、图像、音频、视频，也可以是它们的各种组合。</p><p>统计机器学习，就是从数据出发，提取数据的特征（由谁来提取，是个大是大非问题，下面将给予介绍），抽象出数据的模型，发现数据中的知识，最后又回到数据的分析与预测当中去。</p><p><img src="https://s2.loli.net/2022/02/09/UkzvL7mdjp1is29.png" alt="image-20220209154910160"></p><p>我们今天所有的软件系统，大部分都是人造的长颈鹿，没有学习能力，它所有的能力都是天生给它的，就是人给它的知识，我们都写在了软件代码里面了。<strong>沒有學習能力，看再多世界也沒用</strong></p><p>机器学习近似于找一个好用的函数</p><p><img src="https://s2.loli.net/2022/02/09/tbq6JwCRoyLrkNE.png" alt="image-20220209155304563"></p><p>机器学习的核心特征就是–“从数据中学习，获得性能提升“</p><h1 id="为什么机器学习不容易"><a href="#为什么机器学习不容易" class="headerlink" title="为什么机器学习不容易"></a>为什么机器学习不容易</h1><h2 id="实验：手写体识别"><a href="#实验：手写体识别" class="headerlink" title="实验：手写体识别"></a>实验：手写体识别</h2><h3 id="MNIST介绍"><a href="#MNIST介绍" class="headerlink" title="MNIST介绍"></a>MNIST介绍</h3><p>MNIST数据集分为训练图像和测试图像。训练图像60000张，测试图像10000张，每一个图片代表0-9中的一个数字，且图片大小均为28*28的矩阵。</p><blockquote><p>train-images-idx3-ubyte.gz: training set images (9912422 bytes) 训练图片</p><p>train-labels-idx1-ubyte.gz: training set labels (28881 bytes) 训练标签</p><p>t10k-images-idx3-ubyte.gz: test set images (1648877 bytes) 测试图片</p><p>t10k-labels-idx1-ubyte.gz: test set labels (4542 bytes) 测试标签</p></blockquote><h3 id="获取MNIST数据的几种方法"><a href="#获取MNIST数据的几种方法" class="headerlink" title="获取MNIST数据的几种方法"></a>获取<code>MNIST</code>数据的几种方法</h3><p><strong>方法1</strong><br> 官网下载<code>MNIST</code>数据集的版权在<code>Yann LeCun</code>教授手上，在他的主页下载即可。<a href="http://yann.lecun.com/exdb/mnist/%E4%B8%8B%E8%BD%BD4%E4%B8%AA%60gz%60%E6%96%87%E4%BB%B6%EF%BC%8C%E5%AE%9E%E9%99%85%E4%B8%8A%E8%BF%99%E4%B9%9F%E6%98%AF%E6%97%A7%E7%89%88%60TensorFlow%60%E4%B8%AD%E8%8E%B7%E5%8F%96%60mnist%60%E7%9A%84%E6%96%B9%E6%B3%95%E3%80%82%E6%B3%A8%E6%84%8F%EF%BC%8C%E5%9B%BE%E5%83%8F%E6%95%B0%E6%8D%AE%E5%8F%96%E5%80%BC%E4%B8%BA0%E5%88%B01%E4%B9%8B%E9%97%B4%E3%80%82">http://yann.lecun.com/exdb/mnist/下载4个`gz`文件，实际上这也是旧版`TensorFlow`中获取`mnist`的方法。注意，图像数据取值为0到1之间。</a></p><p><strong>方法2</strong><br>谷歌 <a href="https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz">https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz</a> 下载1个<code>npz</code>文件，实际上这也是新版<code>TensorFlow</code>中获取<code>mnist</code>的方法。注意，图像数据取值为0到255之间。</p><p><strong>方法3</strong><br>通过<code>TensorFlow</code>获取，提前下载好放在这里就可以避免无法下载的问题。</p><figure class="highlight python"><table><tr><td class="gutter"><div class="code-wrapper"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></div></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment">#tensorflow 1.7以前</span><br><span class="hljs-comment">#下载好数据集，放到mnist文件夹下，可以避免无法下载的问题，然后指定datapath来读取。</span><br><span class="hljs-keyword">from</span> tensorflow.examples.tutorials.mnist <span class="hljs-keyword">import</span> input_data<br>datapath = <span class="hljs-string">&quot;./mnist/&quot;</span><br>mnist = input_data.read_data_sets(datapath, one_hot=<span class="hljs-literal">True</span>)<br>train_x = mnist.train.images<br>train_y = mnist.train.labels<br>test_x = mnist.test.images<br>test_y = mnist.text.labels<br> <br><span class="hljs-comment">#tensorflow 1.7以后</span><br><span class="hljs-comment">#下载好数据集mnist.npz，放于~/.keras/datasets/下，可以避免无法下载的问题</span><br><span class="hljs-keyword">import</span> tensorflow <span class="hljs-keyword">as</span> tf <br> <br>(train_x, train_y), (test_x, test_y) = tf.keras.datasets.mnist.load_data(path=<span class="hljs-string">&#x27;mnist.npz&#x27;</span>)<br></code></pre></td></tr></table></figure><p><strong>方法4</strong></p><p>通过<code>Keras</code>获取</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> keras.datasets <span class="hljs-keyword">import</span> mnist<br>(train_x, train_y), (test_x, test_y) = mnist.load_data()<br> <br><span class="hljs-comment">#:\Program Files\Python\Python36-64\Lib\site-packages\keras\datasets</span><br><span class="hljs-comment"># C:\Users\user_name\.keras\datasets</span><br></code></pre></td></tr></table></figure><h3 id="简单实现"><a href="#简单实现" class="headerlink" title="简单实现"></a>简单实现</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment"># -*- coding: utf-8 -*-</span><br><span class="hljs-string">&quot;&quot;&quot;</span><br><span class="hljs-string">程序运行条件：</span><br><span class="hljs-string">（1）安装Python 3.6+</span><br><span class="hljs-string">（2）安装Keras（版本不能太高，2.2.5即可）</span><br><span class="hljs-string">    在命令行输入：</span><br><span class="hljs-string">    pip3 install keras</span><br><span class="hljs-string">    或使用conda安装</span><br><span class="hljs-string">    conda install keras</span><br><span class="hljs-string">&quot;&quot;&quot;</span><br><br><span class="hljs-keyword">import</span> keras <span class="hljs-keyword">as</span> K<br><span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt <span class="hljs-comment"># 绘图</span><br><br><br><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">draw_digital</span>():</span><br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;\nBegin show MNIST image \n&quot;</span>)<br><br>    (train_x, train_y), (test_x, test_y) = K.datasets.mnist.load_data()<br><br>    <span class="hljs-comment"># print(train_x.shape)  # (60000, 28, 28)</span><br>    <span class="hljs-comment"># print(train_y.shape)  # (60000,)</span><br><br>    digital = train_x[<span class="hljs-number">0</span>]<br>    digital = digital.reshape(<span class="hljs-number">28</span>, <span class="hljs-number">28</span>)<br>    <span class="hljs-keyword">for</span> row <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">0</span>, <span class="hljs-number">28</span>):<br>        <span class="hljs-keyword">for</span> col <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">0</span>, <span class="hljs-number">28</span>):<br>            <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;&#123;0:02X&#125; &quot;</span>.<span class="hljs-built_in">format</span>(digital[row][col]), end=<span class="hljs-string">&quot;&quot;</span>)<br>        <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;&quot;</span>)<br><br>    label = train_y[<span class="hljs-number">0</span>]<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;\n手写数字：&quot;</span>, label)<br><br>    plt.imshow(digital, cmap=plt.get_cmap(<span class="hljs-string">&#x27;gray_r&#x27;</span>))<br>    plt.show()<br><br><br><span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">&quot;__main__&quot;</span>:<br>    draw_digital()<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/09/IngJOfcRWtUhx5l.png" alt="image-20220209160010815"></p><h1 id="机器学习的分类"><a href="#机器学习的分类" class="headerlink" title="机器学习的分类"></a>机器学习的分类</h1><p><img src="https://s2.loli.net/2022/02/09/K8inwoVOgeWbzmx.png" alt="image-20220209160155415"></p><h2 id="监督学习"><a href="#监督学习" class="headerlink" title="监督学习"></a>监督学习</h2><p>在<strong>监督式学习</strong>下，输入数据被称为“训练数据”，每组训练数据有一个明确的标识或结果。在建立预测模型的时候，监督式学习建立一个学习过程，将预测结果与“训练数据”的实际结果进行比较，不断的调整预测模型，直到模型的预测结果达到一个预期的准确率。</p><p>监督学习（Supervised Learning）:用数据挖掘大家韩家炜（Jiawei Han）老师的观点来说，<strong>监督学习基本上就是“分类（classification）”的代名词</strong>。它从有标签的训练数据中学习，然后给定某个新数据，预测它的标签（given data, predict labels）。这里的标签（label），其实就是某个事物的分类。</p><blockquote><p>比如说，小时候父母告诉我们某个动物是猫、是狗或是猪，然后我们的大脑里就会形成或猫或狗或猪的印象，然后面前来了一条“新”小狗，如果你能叫出来“这是一条小狗”，那么恭喜你，你的标签分类成功！但如果你说“这是一头小猪”。这时你的监护人就会纠正你的偏差，“乖，不对呦，这是一头小狗”，这样一来二去的训练，就不断更新你的大脑认知体系，聪明如你，下次再遇到这类新的“猫、狗、猪”等，你就会天才般的给出正确“预测”分类。简单来说，监督学习的工作，就是通过有标签的数据训练，获得一个模型，然后通过构建的模型，给新数据添加上特定的标签。</p></blockquote><p><img src="https://s2.loli.net/2022/02/09/vNzXmcSF5dR7qOl.png" alt="监督学习示意图"><br>事实上，整个机器学习的目标，都是使学习得到的模型，能很好地适用于“新样本”，而不是仅仅在训练样本上工作得很好。通过训练得到的模型，适用于新样本的能力，称之为“泛化（generalization)能力”。</p><p><img src="https://s2.loli.net/2022/02/09/DKCqizApBWTk3Sa.png" alt="监督学习的工作流程"></p><h3 id="分类与回归"><a href="#分类与回归" class="headerlink" title="分类与回归"></a>分类与回归</h3><p>诗仙李白在《梦游天姥吟留别》中有一句：<br>云青青兮欲雨</p><p>天气状态，无非是诸如“晴天”、“ 阴天”、雨天或“雪天”等，它们有限的几个<strong>离散</strong>值，非此即彼，这就是一个典型的<strong>分类</strong>问题。 </p><p>《秋浦歌》，里面有句：<br>白发三千丈，缘愁似个长。</p><p>把这类输出状态，看做是连续的。而对输出变量是<strong>连续</strong>的有监督学习，就属于<strong>回归</strong>分析问题。</p><p><img src="https://s2.loli.net/2022/02/09/NJb81TeYf6A27nV.png" alt="一元线性回归示意图"></p><h3 id="监督学习中的损失函数"><a href="#监督学习中的损失函数" class="headerlink" title="监督学习中的损失函数"></a>监督学习中的损失函数</h3><p>衡量实际情况与预测之间的差异——损失函数（loss function），包括但不限于：</p><p><img src="https://s2.loli.net/2022/02/09/Arx5p2BhgwXled3.png" alt="image-20220209161052098"></p><h2 id="无监督学习"><a href="#无监督学习" class="headerlink" title="无监督学习"></a>无监督学习</h2><p>在<strong>非监督式学习</strong>中，数据并不被特别标识，学习模型是为了推断出数据的一些内在结构。常见的应用场景包括关联规则的学习以及聚类等。</p><p>与监督学习相反的是，非监督学习所处的学习环境，都是非标签的数据。韩老师接着说，非监督学习，本质上，就是“<strong>聚类（cluster）</strong>”的近义词</p><p>简单来说，给定数据，从数据中学，能学到什么，就看数据本身具备什么特性了（given data, learn about that data）。我们常说的“物以类聚，人以群分”说得就是“非监督学习”。这里的“类”也好，“群”也罢，事先我们是不知道的。一旦我们归纳出“类”或“群”的特征，如果再要来一个新数据，我们就根据它距离哪个“类”或“群”较近，就“预测”它属于哪个“类”或“群”，从而完成新数据的“分类”或“分群”功能。</p><p><img src="https://s2.loli.net/2022/02/09/L839dNpPoiAfjwV.png" alt="image-20220209161135534"></p><h3 id="k均值聚类"><a href="#k均值聚类" class="headerlink" title="k均值聚类"></a>k均值聚类</h3><p>K均值聚类（k-means) 是基于样本集合划分的聚类算法。K均值聚类将样本集合划分为k个子集，构成k个类，将n个样本分到k个类中，每个样本到其所属类的中心距离最小，每个样本仅属于一个类，这就是k均值聚类，同时根据一个样本仅属于一个类，也表示了k均值聚类是一种硬聚类算法。</p><p><strong>算法过程：</strong></p><p>输入：n个样本的集合</p><p>输出：样本集合的聚类</p><p>过程：</p><p>（1）初始化。随机选择k的样本作为初始聚类的中心。</p><p>（2）对样本进行聚类。针对初始化时选择的聚类中心，计算所有样本到每个中心的距离，默认欧式距离，将每个样本聚集到与其最近的中心的类中，构成聚类结果。</p><p>（3）计算聚类后的类中心，计算每个类的质心，即每个类中样本的均值，作为新的类中心。</p><p>（4）然后重新执行步骤（2）（3），直到聚类结果不再发生改变。</p><p>K均值聚类算法的时间复杂度是O(nmk),n表示样本个数，m表示样本维数，k表示类别个数。<br><img src="https://s2.loli.net/2022/02/09/SE16eRa2jqcI4Nv.png" alt="image-20220209162531126" style="zoom:50%;display:block; margin:auto;" /></p><h2 id="半监督学习"><a href="#半监督学习" class="headerlink" title="半监督学习"></a>半监督学习</h2><p><strong>输入数据部分被标识，部分没有被标识</strong></p><p>半监督学习就是以“已知之认知（标签化的分类信息）”，扩大“未知之领域（通过聚类思想将未知事物归类为已知事物）”。但这里隐含了一个基本假设——“聚类假设（cluster assumption）”，其核心要义就是：“相似的样本，拥有相似的输出”。</p><p><img src="https://s2.loli.net/2022/02/09/c9KROTZvnLQCmjS.png" alt="image-20220209161440566"></p><p>半监督学习（Semi-supervised Learning）：这类学习方式，既用到了标签数据，又用到了非标签数据。有句骂人的话，说某个人“有妈生，没妈教”，抛开这句话骂人的含义，其实它说的是“无监督学习”。但我们绝大多数人，不仅“有妈生，有妈教”，还“有小学教，有中学教，有大学教”，“有人教”，这就是说，有人告诉我们事物的对与错（即对事物打了标签），然后我们可据此改善自己的性情，慢慢把自己调教得更有“教养”，这自然就属于“监督学习”。</p><p>但总有那么一天我们要长大。而长大的标志之一，就是自立。何谓“自立”？就是远离父母、走出校园后，没有人告诉你对与错，一切都要基于自己早期已获取的知识为基础，从社会中学习，扩大并更新自己的认知体系，然后遇到新事物时，我们能“泰然自若”处理，而非茫然“六神无主”。</p><blockquote><p>形式化的定义比较抽象，下面我们列举一个现实生活中的例子，来辅助说明这个概念。假设我们已经学习到：<br>(1) 马晓云同学（数据1）是个牛逼的人（标签：牛逼的人）<br>(2) 马晓腾同学（数据2）是个牛逼的人（标签：牛逼的人）<br>(3) 假设我们并不知道李晓宏同学（数据3）是谁，也不知道他牛逼不牛逼，但考虑他经常和二马同学共同出没于高规格大会，都经常会被达官贵人接见（也就是说他们虽独立，但同分布），我们很容易根据“物以类聚，人以群分”的思想，把李晓宏同学打上标签：他也是一个很牛逼的人！</p></blockquote><p>这样一来，我们的已知领域（标签数据）就扩大了（由两个扩大到三个！），这也就完成了半监督学习。事实上，半监督学习就是以“已知之认知（标签化的分类信息）”，扩大“未知之领域（通过聚类思想将未知事物归类为已知事物）”。但这里隐含了一个基本假设——“聚类假设（cluster assumption）”，其核心要义就是：“相似的样本，拥有相似的输出”。</p><h2 id="强化学习"><a href="#强化学习" class="headerlink" title="强化学习"></a>强化学习</h2><p>强化学习会在没有任何标签的情况下，通过先尝试做出一些行为得到一个结果，通过这个结果是对还是错的反馈，调整之前的行为，就这样不断的调整，算法能够学习到在什么样的情况下选择什么样的行为可以得到最好的结果。</p><p><img src="https://s2.loli.net/2022/02/09/EyBqNYzrx4wtMPL.png" alt="image-20220209161518667"></p><p>如果把机器学习比作一个蛋糕的话，那么强化学习就好比蛋糕上的樱桃，好看但不过是点缀之物，监督学习就好比蛋糕上面的那层糖衣，美味但份额太少。而无（自）监督学习才是蛋糕的本体。<br>在这之中，杨立昆把无监督学习的重要性提到非常高的地位，而且为了让强化学习更加奏效，也离不开无监督学习的支持。而目前还不成气候的半监督学习，甚至都不入杨立昆的法眼。</p><h1 id="三大类机器学习算法"><a href="#三大类机器学习算法" class="headerlink" title="三大类机器学习算法"></a>三大类机器学习算法</h1><p><img src="https://s2.loli.net/2022/02/09/1bpzAWZw6VOh2qe.png" alt="image-20220209161736989"></p><p>监督学习：有标签，有”教师“指导的学习，分类问题</p><p>无监督学习：无标签，利用距离的”亲疏远近“来衡量不同分组，聚类问题</p><p>半监督学习：有部分标签，利用聚类扩大标签。不好研究。。。存在瓶颈</p><p>事实上，我们对半监督学习的现实需求，是非常强烈的。其原因很简单，就是因为人们能收集到的标签数据非常有限，而手工标记数据需要耗费大量的人力物力成本，但非标签数据却大量存在且触手可及，这个现象在互联网数据中更为凸显，因此，“半监督学习”就显得尤为重要性。</p><p>人类的知识，其实都是这样，以“半监督”的滚雪球的模式，越扩越大。“半监督学习”既用到了“监督学习”，也吸纳了“非监督学习”的优点，二者兼顾。</p><p>如此一来，“半监督学习”就有点类似于我们中华文化的“中庸之道”了。</p><h1 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h1><p>人工智能极简入门–张玉宏 第二章</p><p><a href="https://www.zhihu.com/people/yulaiyuhong">https://www.zhihu.com/people/yulaiyuhong</a></p><p><a href="https://blog.csdn.net/weixin_41418263/article/details/113313507">(55条消息) K均值聚类_Chloe-Hao的博客-CSDN博客_k均值聚类</a></p><p><a href="https://blog.csdn.net/u010986753/article/details/105672378/">(55条消息) 【062】MNIST手写体数字识别_小麦粒的Python-CSDN博客</a></p>]]></content>
    
    
    <categories>
      
      <category>人工智能</category>
      
    </categories>
    
    
    <tags>
      
      <tag>人工智能</tag>
      
      <tag>机器学习</tag>
      
    </tags>
    
  </entry>
  
  
  
  <entry>
    <title>python绘制奥运吉祥物冰墩墩</title>
    <link href="/2022/02/09/python%E7%BB%98%E5%88%B6%E5%A5%A5%E8%BF%90%E5%90%89%E7%A5%A5%E7%89%A9%E5%86%B0%E5%A2%A9%E5%A2%A9/"/>
    <url>/2022/02/09/python%E7%BB%98%E5%88%B6%E5%A5%A5%E8%BF%90%E5%90%89%E7%A5%A5%E7%89%A9%E5%86%B0%E5%A2%A9%E5%A2%A9/</url>
    
    <content type="html"><![CDATA[<h1 id="冰墩墩简介"><a href="#冰墩墩简介" class="headerlink" title="冰墩墩简介"></a>冰墩墩简介</h1><p>冰墩墩（英文：<code>Bing Dwen Dwen</code>，汉语拼音：<code>bīng dūn dūn</code>），是<a href="https://baike.baidu.com/item/2022%E5%B9%B4%E5%8C%97%E4%BA%AC%E5%86%AC%E5%AD%A3%E5%A5%A5%E8%BF%90%E4%BC%9A/12061628">2022年北京冬季奥运会</a>的吉祥物。 将熊猫形象与富有超能量的冰晶外壳相结合，头部外壳造型取自冰雪运动头盔，装饰彩色光环，整体形象酷似<a href="https://baike.baidu.com/item/%E8%88%AA%E5%A4%A9%E5%91%98/10130759">航天员</a>。</p><p>2018年8月8日，北京冬奥会和冬残奥会吉祥物全球征集启动仪式举行。2019年9月17日晚，冰墩墩正式亮相  。</p><p>冰墩墩寓意创造非凡、探索未来，体现了追求卓越、引领时代，以及面向未来的无限可能。 </p><span id="more"></span><h1 id="python-turtle绘图"><a href="#python-turtle绘图" class="headerlink" title="python turtle绘图"></a>python turtle绘图</h1><p>主要用的是 Python 自带的 <strong>turtle</strong>库</p><h2 id="turtle库的基础命令介绍"><a href="#turtle库的基础命令介绍" class="headerlink" title="turtle库的基础命令介绍"></a><strong>turtle库的基础命令介绍</strong></h2><h3 id="（1）画布"><a href="#（1）画布" class="headerlink" title="（1）画布"></a>（1）<strong>画布</strong></h3><p>画布是绘图区域，可以设置它的大小和初始位置</p><figure class="highlight plaintext"><table><tr><td class="gutter"><div class="code-wrapper"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></div></td><td class="code"><pre><code class="hljs text">turtle.screensize(1000,600,&#x27;red&#x27;)    大小的设置<br>turtle.setup(width=0.5,height=0.75)  初始位置<br></code></pre></td></tr></table></figure><h3 id="（2）画笔"><a href="#（2）画笔" class="headerlink" title="（2）画笔"></a><strong>（2）画笔</strong></h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><code class="hljs text">（1）画笔运动的命令<br>turtle.forward(a)   向当前画笔方向移动a像素长度<br>turtle.backward(a)  向当前画笔相反方向移动a像素长度<br>turtle.right(a)     顺时针移动<br>aturtle.left(a)     逆时针移动<br>aturtle.pendown()   移动时绘制图形<br>turtle.goto(x,y)    将画笔移动到坐标为x,y的位置<br>turtle.penup()      移动时不绘制图形，提起笔<br>turtle.speed(a)     画笔绘制的速度范围<br>turtle.circle()     画图，半径为正，表示圆心在画笔的左边画圈<br><br>（2）画笔控制命令<br>turtle.pensize(width)   绘制图形的宽度<br>turtle.pencolor()       画笔的颜色<br>turtle.fillcolor(a)     绘制图形的填充颜色<br>turtle.color(a1,a2)     同时设置pencolor=a1,fillcolor=a2<br>turtle.filling()        返回当前是否在填充状态<br>turtle.begin_fill()     准备开始填充图形<br>turtle.end_fill()       填充完成<br>turtle.hideturtle()     隐藏箭头显示<br>turtle.showturtle()     显示箭头<br><br>（3）全局控制命令<br>turtle.clear()   清空turtle窗口,但是turtle的位置和状态不会改变<br>turtle.reset()   清空窗口，重置turtle状态为起始位置<br>turtle.undo()    撤销上一个turtle动作<br></code></pre></td></tr></table></figure><h1 id="硬“肝”不断调整曲线"><a href="#硬“肝”不断调整曲线" class="headerlink" title="硬“肝”不断调整曲线"></a>硬“肝”不断调整曲线</h1><h2 id="turtle绘图小技巧"><a href="#turtle绘图小技巧" class="headerlink" title="turtle绘图小技巧"></a>turtle绘图小技巧</h2><p>通过下面这个语句把你要参考的图先绘制在窗口中，然后再对照着进行绘制调整，就方便许多了。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python">turtle.bgpic(<span class="hljs-string">&#x27;bg.png&#x27;</span>)<br></code></pre></td></tr></table></figure><h2 id="实现效果"><a href="#实现效果" class="headerlink" title="实现效果"></a>实现效果</h2><p><img src="https://s2.loli.net/2022/02/09/wbQG6azJodDFBZq.png" alt="image-20220209145209162"></p><h2 id="完整代码"><a href="#完整代码" class="headerlink" title="完整代码"></a>完整代码</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> turtle<br><br>turtle.title(<span class="hljs-string">&#x27;画个冰墩墩--小马&#x27;</span>)<br><br>turtle.speed(<span class="hljs-number">10</span>)  <span class="hljs-comment"># 速度</span><br><br><span class="hljs-comment"># 左手</span><br>turtle.penup()<br>turtle.goto(<span class="hljs-number">177</span>, <span class="hljs-number">112</span>)<br>turtle.pencolor(<span class="hljs-string">&quot;lightgray&quot;</span>)<br>turtle.pensize(<span class="hljs-number">3</span>)<br>turtle.fillcolor(<span class="hljs-string">&quot;white&quot;</span>)<br>turtle.begin_fill()<br>turtle.pendown()<br>turtle.setheading(<span class="hljs-number">80</span>)<br>turtle.circle(-<span class="hljs-number">45</span>, <span class="hljs-number">200</span>)<br>turtle.circle(-<span class="hljs-number">300</span>, <span class="hljs-number">23</span>)<br>turtle.end_fill()<br><br><span class="hljs-comment"># 左手内</span><br>turtle.penup()<br>turtle.goto(<span class="hljs-number">182</span>, <span class="hljs-number">95</span>)<br>turtle.pencolor(<span class="hljs-string">&quot;black&quot;</span>)<br>turtle.pensize(<span class="hljs-number">1</span>)<br>turtle.fillcolor(<span class="hljs-string">&quot;black&quot;</span>)<br>turtle.begin_fill()<br>turtle.setheading(<span class="hljs-number">95</span>)<br>turtle.pendown()<br>turtle.circle(-<span class="hljs-number">37</span>, <span class="hljs-number">160</span>)<br>turtle.circle(-<span class="hljs-number">20</span>, <span class="hljs-number">50</span>)<br>turtle.circle(-<span class="hljs-number">200</span>, <span class="hljs-number">30</span>)<br>turtle.end_fill()<br><span class="hljs-comment"># 轮廓</span><br><span class="hljs-comment"># 头顶</span><br>turtle.penup()<br>turtle.goto(-<span class="hljs-number">73</span>, <span class="hljs-number">230</span>)<br>turtle.pencolor(<span class="hljs-string">&quot;lightgray&quot;</span>)<br>turtle.pensize(<span class="hljs-number">3</span>)<br>turtle.fillcolor(<span class="hljs-string">&quot;white&quot;</span>)<br>turtle.begin_fill()<br>turtle.pendown()<br>turtle.setheading(<span class="hljs-number">20</span>)<br>turtle.circle(-<span class="hljs-number">250</span>, <span class="hljs-number">35</span>)<br><span class="hljs-comment"># 左耳</span><br>turtle.setheading(<span class="hljs-number">50</span>)<br>turtle.circle(-<span class="hljs-number">42</span>, <span class="hljs-number">180</span>)<br><span class="hljs-comment"># 左侧</span><br>turtle.setheading(-<span class="hljs-number">50</span>)<br>turtle.circle(-<span class="hljs-number">190</span>, <span class="hljs-number">30</span>)<br>turtle.circle(-<span class="hljs-number">320</span>, <span class="hljs-number">45</span>)<br><span class="hljs-comment"># 左腿</span><br>turtle.circle(<span class="hljs-number">120</span>, <span class="hljs-number">30</span>)<br>turtle.circle(<span class="hljs-number">200</span>, <span class="hljs-number">12</span>)<br>turtle.circle(-<span class="hljs-number">18</span>, <span class="hljs-number">85</span>)<br>turtle.circle(-<span class="hljs-number">180</span>, <span class="hljs-number">23</span>)<br>turtle.circle(-<span class="hljs-number">20</span>, <span class="hljs-number">110</span>)<br>turtle.circle(<span class="hljs-number">15</span>, <span class="hljs-number">115</span>)<br>turtle.circle(<span class="hljs-number">100</span>, <span class="hljs-number">12</span>)<br><span class="hljs-comment"># 右腿</span><br>turtle.circle(<span class="hljs-number">15</span>, <span class="hljs-number">120</span>)<br>turtle.circle(-<span class="hljs-number">15</span>, <span class="hljs-number">110</span>)<br>turtle.circle(-<span class="hljs-number">150</span>, <span class="hljs-number">30</span>)<br>turtle.circle(-<span class="hljs-number">15</span>, <span class="hljs-number">70</span>)<br>turtle.circle(-<span class="hljs-number">150</span>, <span class="hljs-number">10</span>)<br>turtle.circle(<span class="hljs-number">200</span>, <span class="hljs-number">35</span>)<br>turtle.circle(-<span class="hljs-number">150</span>, <span class="hljs-number">20</span>)<br><span class="hljs-comment"># 右手</span><br>turtle.setheading(-<span class="hljs-number">120</span>)<br>turtle.circle(<span class="hljs-number">50</span>, <span class="hljs-number">30</span>)<br>turtle.circle(-<span class="hljs-number">35</span>, <span class="hljs-number">200</span>)<br>turtle.circle(-<span class="hljs-number">300</span>, <span class="hljs-number">23</span>)<br><span class="hljs-comment"># 右侧</span><br>turtle.setheading(<span class="hljs-number">86</span>)<br>turtle.circle(-<span class="hljs-number">300</span>, <span class="hljs-number">26</span>)<br><span class="hljs-comment"># 右耳</span><br>turtle.setheading(<span class="hljs-number">122</span>)<br>turtle.circle(-<span class="hljs-number">53</span>, <span class="hljs-number">160</span>)<br>turtle.end_fill()<br><br><span class="hljs-comment"># 右耳内</span><br>turtle.penup()<br>turtle.goto(-<span class="hljs-number">130</span>, <span class="hljs-number">180</span>)<br>turtle.pencolor(<span class="hljs-string">&quot;black&quot;</span>)<br>turtle.pensize(<span class="hljs-number">1</span>)<br>turtle.fillcolor(<span class="hljs-string">&quot;black&quot;</span>)<br>turtle.begin_fill()<br>turtle.pendown()<br>turtle.setheading(<span class="hljs-number">120</span>)<br>turtle.circle(-<span class="hljs-number">28</span>, <span class="hljs-number">160</span>)<br>turtle.setheading(<span class="hljs-number">210</span>)<br>turtle.circle(<span class="hljs-number">150</span>, <span class="hljs-number">20</span>)<br>turtle.end_fill()<br><br><span class="hljs-comment"># 左耳内</span><br>turtle.penup()<br>turtle.goto(<span class="hljs-number">90</span>, <span class="hljs-number">230</span>)<br>turtle.setheading(<span class="hljs-number">40</span>)<br>turtle.begin_fill()<br>turtle.pendown()<br>turtle.circle(-<span class="hljs-number">30</span>, <span class="hljs-number">170</span>)<br>turtle.setheading(<span class="hljs-number">125</span>)<br>turtle.circle(<span class="hljs-number">150</span>, <span class="hljs-number">23</span>)<br>turtle.end_fill()<br><br><span class="hljs-comment"># 右手内</span><br>turtle.penup()<br>turtle.goto(-<span class="hljs-number">180</span>, -<span class="hljs-number">55</span>)<br>turtle.fillcolor(<span class="hljs-string">&quot;black&quot;</span>)<br>turtle.begin_fill()<br>turtle.setheading(-<span class="hljs-number">120</span>)<br>turtle.pendown()<br>turtle.circle(<span class="hljs-number">50</span>, <span class="hljs-number">30</span>)<br>turtle.circle(-<span class="hljs-number">27</span>, <span class="hljs-number">200</span>)<br>turtle.circle(-<span class="hljs-number">300</span>, <span class="hljs-number">20</span>)<br>turtle.setheading(-<span class="hljs-number">90</span>)<br>turtle.circle(<span class="hljs-number">300</span>, <span class="hljs-number">14</span>)<br>turtle.end_fill()<br><br><span class="hljs-comment"># 左腿内</span><br>turtle.penup()<br>turtle.goto(<span class="hljs-number">108</span>, -<span class="hljs-number">168</span>)<br>turtle.fillcolor(<span class="hljs-string">&quot;black&quot;</span>)<br>turtle.begin_fill()<br>turtle.pendown()<br>turtle.setheading(-<span class="hljs-number">115</span>)<br>turtle.circle(<span class="hljs-number">110</span>, <span class="hljs-number">15</span>)<br>turtle.circle(<span class="hljs-number">200</span>, <span class="hljs-number">10</span>)<br>turtle.circle(-<span class="hljs-number">18</span>, <span class="hljs-number">80</span>)<br>turtle.circle(-<span class="hljs-number">180</span>, <span class="hljs-number">13</span>)<br>turtle.circle(-<span class="hljs-number">20</span>, <span class="hljs-number">90</span>)<br>turtle.circle(<span class="hljs-number">15</span>, <span class="hljs-number">60</span>)<br>turtle.setheading(<span class="hljs-number">42</span>)<br>turtle.circle(-<span class="hljs-number">200</span>, <span class="hljs-number">29</span>)<br>turtle.end_fill()<br><span class="hljs-comment"># 右腿内</span><br>turtle.penup()<br>turtle.goto(-<span class="hljs-number">38</span>, -<span class="hljs-number">210</span>)<br>turtle.fillcolor(<span class="hljs-string">&quot;black&quot;</span>)<br>turtle.begin_fill()<br>turtle.pendown()<br>turtle.setheading(-<span class="hljs-number">155</span>)<br>turtle.circle(<span class="hljs-number">15</span>, <span class="hljs-number">100</span>)<br>turtle.circle(-<span class="hljs-number">10</span>, <span class="hljs-number">110</span>)<br>turtle.circle(-<span class="hljs-number">100</span>, <span class="hljs-number">30</span>)<br>turtle.circle(-<span class="hljs-number">15</span>, <span class="hljs-number">65</span>)<br>turtle.circle(-<span class="hljs-number">100</span>, <span class="hljs-number">10</span>)<br>turtle.circle(<span class="hljs-number">200</span>, <span class="hljs-number">15</span>)<br>turtle.setheading(-<span class="hljs-number">14</span>)<br>turtle.circle(-<span class="hljs-number">200</span>, <span class="hljs-number">27</span>)<br>turtle.end_fill()<br><br><span class="hljs-comment"># 右眼</span><br><span class="hljs-comment"># 眼圈</span><br>turtle.penup()<br>turtle.goto(-<span class="hljs-number">64</span>, <span class="hljs-number">120</span>)<br>turtle.begin_fill()<br>turtle.pendown()<br>turtle.setheading(<span class="hljs-number">40</span>)<br>turtle.circle(-<span class="hljs-number">35</span>, <span class="hljs-number">152</span>)<br>turtle.circle(-<span class="hljs-number">100</span>, <span class="hljs-number">50</span>)<br>turtle.circle(-<span class="hljs-number">35</span>, <span class="hljs-number">130</span>)<br>turtle.circle(-<span class="hljs-number">100</span>, <span class="hljs-number">50</span>)<br>turtle.end_fill()<br><span class="hljs-comment"># 眼珠</span><br>turtle.penup()<br>turtle.goto(-<span class="hljs-number">47</span>, <span class="hljs-number">55</span>)<br>turtle.fillcolor(<span class="hljs-string">&quot;white&quot;</span>)<br>turtle.begin_fill()<br>turtle.pendown()<br>turtle.setheading(<span class="hljs-number">0</span>)<br>turtle.circle(<span class="hljs-number">25</span>, <span class="hljs-number">360</span>)<br>turtle.end_fill()<br>turtle.penup()<br>turtle.goto(-<span class="hljs-number">45</span>, <span class="hljs-number">62</span>)<br>turtle.pencolor(<span class="hljs-string">&quot;darkslategray&quot;</span>)<br>turtle.fillcolor(<span class="hljs-string">&quot;darkslategray&quot;</span>)<br>turtle.begin_fill()<br>turtle.pendown()<br>turtle.setheading(<span class="hljs-number">0</span>)<br>turtle.circle(<span class="hljs-number">19</span>, <span class="hljs-number">360</span>)<br>turtle.end_fill()<br>turtle.penup()<br>turtle.goto(-<span class="hljs-number">45</span>, <span class="hljs-number">68</span>)<br>turtle.fillcolor(<span class="hljs-string">&quot;black&quot;</span>)<br>turtle.begin_fill()<br>turtle.pendown()<br>turtle.setheading(<span class="hljs-number">0</span>)<br>turtle.circle(<span class="hljs-number">10</span>, <span class="hljs-number">360</span>)<br>turtle.end_fill()<br>turtle.penup()<br>turtle.goto(-<span class="hljs-number">47</span>, <span class="hljs-number">86</span>)<br>turtle.pencolor(<span class="hljs-string">&quot;white&quot;</span>)<br>turtle.fillcolor(<span class="hljs-string">&quot;white&quot;</span>)<br>turtle.begin_fill()<br>turtle.pendown()<br>turtle.setheading(<span class="hljs-number">0</span>)<br>turtle.circle(<span class="hljs-number">5</span>, <span class="hljs-number">360</span>)<br>turtle.end_fill()<br><br><span class="hljs-comment"># 左眼</span><br><span class="hljs-comment"># 眼圈</span><br>turtle.penup()<br>turtle.goto(<span class="hljs-number">51</span>, <span class="hljs-number">82</span>)<br>turtle.fillcolor(<span class="hljs-string">&quot;black&quot;</span>)<br>turtle.begin_fill()<br>turtle.pendown()<br>turtle.setheading(<span class="hljs-number">120</span>)<br>turtle.circle(-<span class="hljs-number">32</span>, <span class="hljs-number">152</span>)<br>turtle.circle(-<span class="hljs-number">100</span>, <span class="hljs-number">55</span>)<br>turtle.circle(-<span class="hljs-number">25</span>, <span class="hljs-number">120</span>)<br>turtle.circle(-<span class="hljs-number">120</span>, <span class="hljs-number">45</span>)<br>turtle.end_fill()<br><span class="hljs-comment"># 眼珠</span><br>turtle.penup()<br>turtle.goto(<span class="hljs-number">79</span>, <span class="hljs-number">60</span>)<br>turtle.fillcolor(<span class="hljs-string">&quot;white&quot;</span>)<br>turtle.begin_fill()<br>turtle.pendown()<br>turtle.setheading(<span class="hljs-number">0</span>)<br>turtle.circle(<span class="hljs-number">24</span>, <span class="hljs-number">360</span>)<br>turtle.end_fill()<br>turtle.penup()<br>turtle.goto(<span class="hljs-number">79</span>, <span class="hljs-number">64</span>)<br>turtle.pencolor(<span class="hljs-string">&quot;darkslategray&quot;</span>)<br>turtle.fillcolor(<span class="hljs-string">&quot;darkslategray&quot;</span>)<br>turtle.begin_fill()<br>turtle.pendown()<br>turtle.setheading(<span class="hljs-number">0</span>)<br>turtle.circle(<span class="hljs-number">19</span>, <span class="hljs-number">360</span>)<br>turtle.end_fill()<br>turtle.penup()<br>turtle.goto(<span class="hljs-number">79</span>, <span class="hljs-number">70</span>)<br>turtle.fillcolor(<span class="hljs-string">&quot;black&quot;</span>)<br>turtle.begin_fill()<br>turtle.pendown()<br>turtle.setheading(<span class="hljs-number">0</span>)<br>turtle.circle(<span class="hljs-number">10</span>, <span class="hljs-number">360</span>)<br>turtle.end_fill()<br>turtle.penup()<br>turtle.goto(<span class="hljs-number">79</span>, <span class="hljs-number">88</span>)<br>turtle.pencolor(<span class="hljs-string">&quot;white&quot;</span>)<br>turtle.fillcolor(<span class="hljs-string">&quot;white&quot;</span>)<br>turtle.begin_fill()<br>turtle.pendown()<br>turtle.setheading(<span class="hljs-number">0</span>)<br>turtle.circle(<span class="hljs-number">5</span>, <span class="hljs-number">360</span>)<br>turtle.end_fill()<br><br><span class="hljs-comment"># 鼻子</span><br>turtle.penup()<br>turtle.goto(<span class="hljs-number">37</span>, <span class="hljs-number">80</span>)<br>turtle.fillcolor(<span class="hljs-string">&quot;black&quot;</span>)<br>turtle.begin_fill()<br>turtle.pendown()<br>turtle.circle(-<span class="hljs-number">8</span>, <span class="hljs-number">130</span>)<br>turtle.circle(-<span class="hljs-number">22</span>, <span class="hljs-number">100</span>)<br>turtle.circle(-<span class="hljs-number">8</span>, <span class="hljs-number">130</span>)<br>turtle.end_fill()<br><br><span class="hljs-comment"># 嘴</span><br>turtle.penup()<br>turtle.goto(-<span class="hljs-number">15</span>, <span class="hljs-number">48</span>)<br>turtle.setheading(-<span class="hljs-number">36</span>)<br>turtle.begin_fill()<br>turtle.pendown()<br>turtle.circle(<span class="hljs-number">60</span>, <span class="hljs-number">70</span>)<br>turtle.setheading(-<span class="hljs-number">132</span>)<br>turtle.circle(-<span class="hljs-number">45</span>, <span class="hljs-number">100</span>)<br>turtle.end_fill()<br><br><span class="hljs-comment"># 彩虹圈</span><br>turtle.penup()<br>turtle.goto(-<span class="hljs-number">135</span>, <span class="hljs-number">120</span>)<br>turtle.pensize(<span class="hljs-number">5</span>)<br>turtle.pencolor(<span class="hljs-string">&quot;cyan&quot;</span>)<br>turtle.pendown()<br>turtle.setheading(<span class="hljs-number">60</span>)<br>turtle.circle(-<span class="hljs-number">165</span>, <span class="hljs-number">150</span>)<br>turtle.circle(-<span class="hljs-number">130</span>, <span class="hljs-number">78</span>)<br>turtle.circle(-<span class="hljs-number">250</span>, <span class="hljs-number">30</span>)<br>turtle.circle(-<span class="hljs-number">138</span>, <span class="hljs-number">105</span>)<br>turtle.penup()<br>turtle.goto(-<span class="hljs-number">131</span>, <span class="hljs-number">116</span>)<br>turtle.pencolor(<span class="hljs-string">&quot;slateblue&quot;</span>)<br>turtle.pendown()<br>turtle.setheading(<span class="hljs-number">60</span>)<br>turtle.circle(-<span class="hljs-number">160</span>, <span class="hljs-number">144</span>)<br>turtle.circle(-<span class="hljs-number">120</span>, <span class="hljs-number">78</span>)<br>turtle.circle(-<span class="hljs-number">242</span>, <span class="hljs-number">30</span>)<br>turtle.circle(-<span class="hljs-number">135</span>, <span class="hljs-number">105</span>)<br>turtle.penup()<br>turtle.goto(-<span class="hljs-number">127</span>, <span class="hljs-number">112</span>)<br>turtle.pencolor(<span class="hljs-string">&quot;orangered&quot;</span>)<br>turtle.pendown()<br>turtle.setheading(<span class="hljs-number">60</span>)<br>turtle.circle(-<span class="hljs-number">155</span>, <span class="hljs-number">136</span>)<br>turtle.circle(-<span class="hljs-number">116</span>, <span class="hljs-number">86</span>)<br>turtle.circle(-<span class="hljs-number">220</span>, <span class="hljs-number">30</span>)<br>turtle.circle(-<span class="hljs-number">134</span>, <span class="hljs-number">103</span>)<br>turtle.penup()<br>turtle.goto(-<span class="hljs-number">123</span>, <span class="hljs-number">108</span>)<br>turtle.pencolor(<span class="hljs-string">&quot;gold&quot;</span>)<br>turtle.pendown()<br>turtle.setheading(<span class="hljs-number">60</span>)<br>turtle.circle(-<span class="hljs-number">150</span>, <span class="hljs-number">136</span>)<br>turtle.circle(-<span class="hljs-number">104</span>, <span class="hljs-number">86</span>)<br>turtle.circle(-<span class="hljs-number">220</span>, <span class="hljs-number">30</span>)<br>turtle.circle(-<span class="hljs-number">126</span>, <span class="hljs-number">102</span>)<br>turtle.penup()<br>turtle.goto(-<span class="hljs-number">120</span>, <span class="hljs-number">104</span>)<br>turtle.pencolor(<span class="hljs-string">&quot;greenyellow&quot;</span>)<br>turtle.pendown()<br>turtle.setheading(<span class="hljs-number">60</span>)<br>turtle.circle(-<span class="hljs-number">145</span>, <span class="hljs-number">136</span>)<br>turtle.circle(-<span class="hljs-number">90</span>, <span class="hljs-number">83</span>)<br>turtle.circle(-<span class="hljs-number">220</span>, <span class="hljs-number">30</span>)<br>turtle.circle(-<span class="hljs-number">120</span>, <span class="hljs-number">100</span>)<br>turtle.penup()<br><br><span class="hljs-comment"># 爱心</span><br>turtle.penup()<br>turtle.goto(<span class="hljs-number">220</span>, <span class="hljs-number">115</span>)<br>turtle.pencolor(<span class="hljs-string">&quot;brown&quot;</span>)<br>turtle.pensize(<span class="hljs-number">1</span>)<br>turtle.fillcolor(<span class="hljs-string">&quot;brown&quot;</span>)<br>turtle.begin_fill()<br>turtle.pendown()<br>turtle.setheading(<span class="hljs-number">36</span>)<br>turtle.circle(-<span class="hljs-number">8</span>, <span class="hljs-number">180</span>)<br>turtle.circle(-<span class="hljs-number">60</span>, <span class="hljs-number">24</span>)<br>turtle.setheading(<span class="hljs-number">110</span>)<br>turtle.circle(-<span class="hljs-number">60</span>, <span class="hljs-number">24</span>)<br>turtle.circle(-<span class="hljs-number">8</span>, <span class="hljs-number">180</span>)<br>turtle.end_fill()<br><br><span class="hljs-comment"># 五环</span><br>turtle.penup()<br>turtle.goto(-<span class="hljs-number">5</span>, -<span class="hljs-number">170</span>)<br>turtle.pendown()<br>turtle.pencolor(<span class="hljs-string">&quot;blue&quot;</span>)<br>turtle.circle(<span class="hljs-number">6</span>)<br>turtle.penup()<br>turtle.goto(<span class="hljs-number">10</span>, -<span class="hljs-number">170</span>)<br>turtle.pendown()<br>turtle.pencolor(<span class="hljs-string">&quot;black&quot;</span>)<br>turtle.circle(<span class="hljs-number">6</span>)<br>turtle.penup()<br>turtle.goto(<span class="hljs-number">25</span>, -<span class="hljs-number">170</span>)<br>turtle.pendown()<br>turtle.pencolor(<span class="hljs-string">&quot;brown&quot;</span>)<br>turtle.circle(<span class="hljs-number">6</span>)<br>turtle.penup()<br>turtle.goto(<span class="hljs-number">2</span>, -<span class="hljs-number">175</span>)<br>turtle.pendown()<br>turtle.pencolor(<span class="hljs-string">&quot;lightgoldenrod&quot;</span>)<br>turtle.circle(<span class="hljs-number">6</span>)<br>turtle.penup()<br>turtle.goto(<span class="hljs-number">16</span>, -<span class="hljs-number">175</span>)<br>turtle.pendown()<br>turtle.pencolor(<span class="hljs-string">&quot;green&quot;</span>)<br>turtle.circle(<span class="hljs-number">6</span>)<br>turtle.penup()<br><br>turtle.pencolor(<span class="hljs-string">&quot;black&quot;</span>)<br>turtle.goto(-<span class="hljs-number">16</span>, -<span class="hljs-number">160</span>)<br>turtle.write(<span class="hljs-string">&quot;BEIJING 2022&quot;</span>, font=(<span class="hljs-string">&#x27;Arial&#x27;</span>, <span class="hljs-number">10</span>, <span class="hljs-string">&#x27;bold italic&#x27;</span>))<br>turtle.hideturtle()<br><br>turtle.done()<br></code></pre></td></tr></table></figure><h1 id="opencv-turtle自动绘图"><a href="#opencv-turtle自动绘图" class="headerlink" title="opencv+turtle自动绘图"></a>opencv+turtle自动绘图</h1><h2 id="先看效果"><a href="#先看效果" class="headerlink" title="先看效果"></a>先看效果</h2><p><img src="https://s2.loli.net/2022/02/09/2NgdixPQ3yZKkBC.png" alt="image-20220209151707506"></p><h2 id="实现过程"><a href="#实现过程" class="headerlink" title="实现过程"></a>实现过程</h2><p>turtle是python的一个很好玩的自动绘图工具。然而，用它来画一幅画需要提供大量的坐标点。有的人为了用它画出一幅好看的画不惜去手工计算图片线稿的描点的位置。心疼一秒。<br>其实我们完全可以用计算机图像识别来自动获取图片边缘的位置坐标，比如Opencv。<br>我们先直接上python的opencv一个基本案例。</p><blockquote><p>记得先安装opencv-python库</p></blockquote><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> cv2<br>img = cv2.imread(<span class="hljs-string">&quot;bingdundun.png&quot;</span>)<span class="hljs-comment">#读取一张图片</span><br>cv2.imshow(<span class="hljs-string">&quot;窗口标题&quot;</span>,img)<span class="hljs-comment">#在一个窗口显示图片</span><br></code></pre></td></tr></table></figure><p>cv2.imread()是读取一个图像文件，然后将图像的像素信息转化成一个numpy矩阵，并返回<br>cv2.imshow()则是读取一个numpy矩阵信息，将其作为像素信息在新窗口中打印出来。<br>ok，读取图片工作完成了，那我们现在来获取图片的边缘信息</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs python">point=cv2.Canny(img, <span class="hljs-number">000</span>, <span class="hljs-number">200</span>)<br></code></pre></td></tr></table></figure><p>这是边缘检测函数，将img图像的边缘像素信息作为numpy矩阵返回，里面的0和200这个参数是阈值范围参数，可自行调节。<br>虽然得到了边缘位置的信息，但这个矩阵信息却是显示的图像的矩阵的旋转矩阵。因此我们还需要对所得矩阵进行旋转，否则可能会得到倒过来的图像。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> numpy<br>point=numpy.rot90(black,k=<span class="hljs-number">3</span>)<br></code></pre></td></tr></table></figure><p>numpy.rot90()这个函数是矩阵顺时针旋转90度的函数，k代表旋转的次数，经过我的测试，要旋转3次才矫正(也就是逆时针一次)。<br>得到绘图点的像素信息后，我们开始用turtle进行绘图</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> turtle<br><span class="hljs-keyword">for</span> y <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">0</span>,<span class="hljs-built_in">len</span>(point)):<br>    <span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">0</span>,<span class="hljs-built_in">len</span>(point[y])):<br>        <span class="hljs-keyword">if</span> point[y][x]!=<span class="hljs-number">0</span>:<br>            turtle.penup()<br>            turtle.goto(y,x)<br>            turtle.pendown()<br>            turtle.goto(y,x)<br>            turtle.penup()<br></code></pre></td></tr></table></figure><p>这里就是直接判断x，y坐标下绘图点矩阵的像素信息是否为0，因为绘图点矩阵是通过canny边缘识别得到的，故除了边缘意外的位置像素值都为0.这样就能描绘出一张图片的线稿了<br>此外还有其他参数可以调节，比如缩放图像尺寸,笔的大小，绘图的中心位置，绘图速度等等。</p><h2 id="完整代码-1"><a href="#完整代码-1" class="headerlink" title="完整代码"></a>完整代码</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> cv2<br><span class="hljs-keyword">import</span> turtle<br><span class="hljs-keyword">import</span> numpy<br>img = cv2.imread(<span class="hljs-string">&quot;i.png&quot;</span>)<br>cv2.imshow(<span class="hljs-string">&quot;biaoti&quot;</span>,img)<br>black=cv2.Canny(img, <span class="hljs-number">000</span>, <span class="hljs-number">200</span>)<br>height, width=black.shape[:<span class="hljs-number">2</span>]<br>point = cv2.resize(black, (<span class="hljs-built_in">int</span>(width/<span class="hljs-number">4</span>), <span class="hljs-built_in">int</span>(height/<span class="hljs-number">4</span>)), interpolation=cv2.INTER_CUBIC)<br>point=numpy.rot90(point,k=<span class="hljs-number">3</span>)<br>turtle.setup(<span class="hljs-number">600</span>,<span class="hljs-number">600</span>)<br>x0=<span class="hljs-built_in">int</span>(<span class="hljs-built_in">len</span>(point[<span class="hljs-number">0</span>])/<span class="hljs-number">2</span>)<br>y0=<span class="hljs-built_in">int</span>(<span class="hljs-built_in">len</span>(point)/<span class="hljs-number">2</span>)<br>turtle.pensize(<span class="hljs-number">3</span>)<br><br>turtle.speed(<span class="hljs-number">1000</span>)<br><span class="hljs-keyword">for</span> y <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">0</span>,<span class="hljs-built_in">len</span>(point),<span class="hljs-number">2</span>):<br>    <span class="hljs-keyword">for</span> x <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">0</span>,<span class="hljs-built_in">len</span>(point[y]),<span class="hljs-number">2</span>):<br>        <span class="hljs-keyword">if</span> point[y][x]!=<span class="hljs-number">0</span>:<br>            <span class="hljs-built_in">print</span>(y,x)<br>            turtle.penup()<br>            turtle.goto(y-y0,x-x0)<br>            turtle.pendown()<br>            turtle.goto(y-y0,x-x0)<br>            turtle.penup()<br><span class="hljs-keyword">while</span> <span class="hljs-number">1</span>:<br>    <span class="hljs-keyword">pass</span><br></code></pre></td></tr></table></figure><h1 id="使用opencv找轮廓"><a href="#使用opencv找轮廓" class="headerlink" title="使用opencv找轮廓"></a>使用opencv找轮廓</h1><h2 id="实现效果-1"><a href="#实现效果-1" class="headerlink" title="实现效果"></a>实现效果</h2><p><img src="https://s2.loli.net/2022/02/09/QnazJM9qhvcuTij.png" alt="image-20220209152121194"></p><h2 id="完整代码-2"><a href="#完整代码-2" class="headerlink" title="完整代码"></a>完整代码</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment"># -*- coding:utf-8 -*-</span><br><span class="hljs-comment"># __author__ = &quot;mayuke&quot;</span><br><br><span class="hljs-comment"># 导入模块</span><br><span class="hljs-keyword">import</span> turtle<br><span class="hljs-keyword">import</span> cv2 <span class="hljs-keyword">as</span> cv<br><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np<br><br><span class="hljs-comment"># 读取图片，并设置相关参数</span><br>src = cv.imread(<span class="hljs-string">&quot;img.jpg&quot;</span>)<br><span class="hljs-comment"># print(src.shape)</span><br>cv.imshow(<span class="hljs-string">&#x27;s1&#x27;</span>, src)<br>width = src.shape[<span class="hljs-number">1</span>]<br>hight = src.shape[<span class="hljs-number">0</span>]<br><span class="hljs-built_in">print</span>(width, hight)<br>turtle.setup(width + <span class="hljs-number">15</span>, hight + <span class="hljs-number">15</span>)<br>turtle.bgcolor(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>)<br>turtle.pencolor(<span class="hljs-number">1</span>, <span class="hljs-number">1</span>, <span class="hljs-number">1</span>)<br><br><span class="hljs-comment"># 用一个函数将图片左上角设置成坐标原点（0,0）</span><br><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">y</span>(<span class="hljs-params">x, y</span>):</span><br>    x = x - <span class="hljs-number">1</span> / <span class="hljs-number">2</span> * width<br>    y = -(y - <span class="hljs-number">1</span> / <span class="hljs-number">2</span> * hight)<br>    <span class="hljs-keyword">return</span> x, y<br><br><span class="hljs-comment"># 将图片转成灰度图并进行二值化</span><br>gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)<br>ret, image = cv.threshold(gray, <span class="hljs-number">0</span>, <span class="hljs-number">255</span>, cv.THRESH_OTSU)<br><br><span class="hljs-comment"># 使用opencv找轮廓</span><br>counters, re = cv.findContours(image, cv.RETR_TREE, cv.CHAIN_APPROX_NONE)<br><span class="hljs-built_in">print</span>(<span class="hljs-string">&#x27;轮廓个数：&#x27;</span>, <span class="hljs-built_in">len</span>(counters))<br><br><span class="hljs-comment"># 遍历轮廓进行画图</span><br><span class="hljs-keyword">for</span> i, con <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(counters):<br><br>    area = cv.contourArea(con)<br><br>    con = np.reshape(con, (con.shape[<span class="hljs-number">0</span>], <span class="hljs-number">2</span>))<br><br>    turtle.goto(y(con[<span class="hljs-number">0</span>, <span class="hljs-number">0</span>], con[<span class="hljs-number">0</span>, <span class="hljs-number">1</span>]))<br>    turtle.pendown()<br><br>    biao_x1 = np.argmin(con[:, <span class="hljs-number">0</span>])<br>    x1 = con[biao_x1, <span class="hljs-number">0</span>]<br>    y1 = con[biao_x1, <span class="hljs-number">1</span>]<br>    <span class="hljs-comment"># print(&#x27;x1,y1=&#x27;,x1,y1)</span><br><br>    biao_x2 = np.argmax(con[:, <span class="hljs-number">0</span>])<br>    x2 = con[biao_x2, <span class="hljs-number">0</span>]<br>    y2 = con[biao_x2, <span class="hljs-number">1</span>]<br>    <span class="hljs-comment"># print(&#x27;x2,y2=&#x27;, x2, y2)</span><br><br>    biao_y3 = np.argmin(con[:, <span class="hljs-number">1</span>])<br>    x3 = con[biao_y3, <span class="hljs-number">0</span>]<br>    y3 = con[biao_y3, <span class="hljs-number">1</span>]<br>    <span class="hljs-comment"># print(&#x27;x3,y3=&#x27;, x3, y3)</span><br>    <span class="hljs-comment"># 下边坐标</span><br>    biao_y4 = np.argmin(con[:, <span class="hljs-number">1</span>])<br>    x4 = con[biao_y4, <span class="hljs-number">0</span>]<br>    y4 = con[biao_y4, <span class="hljs-number">1</span>]<br>    <span class="hljs-comment"># print(&#x27;x4,y4=&#x27;, x4, y4)</span><br><br>    x1 = x1<br>    <span class="hljs-comment"># right</span><br>    x2 = x2<br>    <span class="hljs-comment"># up</span><br>    y3 = y3<br>    <span class="hljs-comment"># bottom</span><br>    y4 = y4<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&#x27;x1,y1=&#x27;</span>, x1, y1)<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&#x27;x2,y2=&#x27;</span>, x2, y2)<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&#x27;x3,y3=&#x27;</span>, x3, y3)<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&#x27;x4,y4=&#x27;</span>, x4, y4)<br>    <span class="hljs-keyword">if</span> x1 &lt; width <span class="hljs-keyword">and</span> x2 &gt;= <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> y3 &lt; hight <span class="hljs-keyword">and</span> y4 &gt;= <span class="hljs-number">0</span>:<br>        a1 = image[y1, x1] / <span class="hljs-number">255</span><br><br>        a2 = image[y2, x2] / <span class="hljs-number">255</span><br><br>        a3 = image[y3, x3] / <span class="hljs-number">255</span><br><br>        a4 = image[y4, x4] / <span class="hljs-number">255</span><br>    <span class="hljs-keyword">else</span>:<br>        a1 = a2 = a3 = a4 = <span class="hljs-number">0</span><br><br>    a = a1 + a2 + a3 + a4<br><br>    turtle.begin_fill()<br><br>    <span class="hljs-keyword">if</span> a &gt; <span class="hljs-number">5</span>:<br>        turtle.fillcolor(<span class="hljs-number">1</span>, <span class="hljs-number">1</span>, <span class="hljs-number">1</span>)<br>    <span class="hljs-keyword">elif</span> a &lt;= <span class="hljs-number">5</span>:<br>        turtle.fillcolor(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>)<br>    <span class="hljs-comment"># 画图</span><br>    <span class="hljs-keyword">for</span> shu, c <span class="hljs-keyword">in</span> <span class="hljs-built_in">enumerate</span>(con):<br>        turtle.goto(y(c[<span class="hljs-number">0</span>], c[<span class="hljs-number">1</span>]))<br>    turtle.goto(y(con[<span class="hljs-number">0</span>, <span class="hljs-number">0</span>], con[<span class="hljs-number">0</span>, <span class="hljs-number">1</span>]))<br>    turtle.end_fill()<br>    turtle.penup()<br><br>turtle.mainloop()<br><br></code></pre></td></tr></table></figure><h1 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h1><p><a href="https://it.sohu.com/a/521259005_121124358">Python绘制冬奥吉祥物“冰墩墩”_turtle_goto_Crossin (sohu.com)</a></p><p><a href="https://blog.csdn.net/qq_39096769/article/details/105212737">(55条消息) opencv+turtle自动绘图_林雪飞的博客-CSDN博客_opencv 线稿</a></p><p><a href="https://blog.csdn.net/qq_45087786/article/details/115445152?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2~default~CTRLIST~Rate-1.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2~default~CTRLIST~Rate-1.pc_relevant_default&utm_relevant_index=1">(55条消息) python 用turtle自动画图_qq 1735375343的博客-CSDN博客_python自动绘图</a></p>]]></content>
    
    
    <categories>
      
      <category>随笔</category>
      
    </categories>
    
    
    <tags>
      
      <tag>随笔</tag>
      
      <tag>python</tag>
      
      <tag>turtle</tag>
      
    </tags>
    
  </entry>
  
  
  
  <entry>
    <title>img margin 0 auto; 图片水平居中布局无效</title>
    <link href="/2022/02/08/img%20margin%200%20auto%20%E5%9B%BE%E7%89%87%E6%B0%B4%E5%B9%B3%E5%B1%85%E4%B8%AD%E6%97%A0%E6%95%88/"/>
    <url>/2022/02/08/img%20margin%200%20auto%20%E5%9B%BE%E7%89%87%E6%B0%B4%E5%B9%B3%E5%B1%85%E4%B8%AD%E6%97%A0%E6%95%88/</url>
    
    <content type="html"><![CDATA[<h1 id="发现问题"><a href="#发现问题" class="headerlink" title="发现问题"></a>发现问题</h1><p>在<code>typora</code>中插入图片使用<code>style=&quot;zoom:67%;&quot;</code>缩放属性，在<code>typora</code>中仍是居中显示的，但是发布博客之后就没有了居中效果，于是添加样式<code>margin:0 auto; </code>发现仍然无法居中</p><p><code>&lt;img src=&quot;https://s2.loli.net/2022/02/08/zW6XYcisfp5QHTR.png&quot; alt=&quot;image-20220208153609189&quot; style=&quot;zoom:67%; margin:auto;&quot; /&gt;</code></p><h1 id="解决问题"><a href="#解决问题" class="headerlink" title="解决问题"></a>解决问题</h1><p><code>img</code>是一种可替换元素，虽然它可以设置宽高，但其本质上还是一个行内元素，所以在使用<code>margin：0 auto</code>的方式设置其水平居中时、必须先将<code>img</code>设置<code>display:block;</code>再设置<code>margin：0 auto</code>才会生效；于是改成下面的写法</p><p><code>&lt;img src=&quot;https://s2.loli.net/2022/02/08/zW6XYcisfp5QHTR.png&quot; alt=&quot;image-20220208153609189&quot; style=&quot;zoom:67%; display:block; margin:auto;&quot; /&gt;</code></p><h1 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h1><p><a href="https://blog.csdn.net/weixin_45944877/article/details/119581116">(55条消息) 图片的垂直水平居中；vertical-align：middle；margin:0 auto和text-align:center失效的问题_CoderLittleWhite的博客-CSDN博客</a></p>]]></content>
    
    
    <categories>
      
      <category>随笔</category>
      
    </categories>
    
    
    <tags>
      
      <tag>随笔</tag>
      
      <tag>html</tag>
      
      <tag>前端</tag>
      
      <tag>css</tag>
      
    </tags>
    
  </entry>
  
  
  
  <entry>
    <title>手把手搭建一个简易神经网络</title>
    <link href="/2022/02/08/%E6%89%8B%E6%8A%8A%E6%89%8B%E6%90%AD%E5%BB%BA%E4%B8%80%E4%B8%AA%E7%AE%80%E6%98%93%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C/"/>
    <url>/2022/02/08/%E6%89%8B%E6%8A%8A%E6%89%8B%E6%90%AD%E5%BB%BA%E4%B8%80%E4%B8%AA%E7%AE%80%E6%98%93%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C/</url>
    
    <content type="html"><![CDATA[<h1 id="搭建一个简易神经网络"><a href="#搭建一个简易神经网络" class="headerlink" title="搭建一个简易神经网络"></a>搭建一个简易神经网络</h1><p>了解神经网络工作方式的最佳途径莫过于亲自创建一个神经网络，本文将利用感知机解决<strong>异或</strong>问题。</p><p>神经网络(NN)又称人工神经网络(ANN)，是机器学习领域中基于生物神经网络概念的学习算法的一个子集。</p><p>拥有五年以上经验的德国机器学习专家Andrey Bulezyuk声称：<strong>“神经网络正在彻底改变机器学习，因为它们能够在广泛的学科和行业中为抽象对象高效建模。”</strong></p><span id="more"></span><h2 id="神经网络的发展历史"><a href="#神经网络的发展历史" class="headerlink" title="神经网络的发展历史"></a>神经网络的发展历史</h2><p>追根溯源，神经网络诞生于人类对于人脑和智能的追问。而这个追问经历了旷远蒙昧的精神至上学说，直到 19 世纪 20 年代。</p><p>奥地利医生 Franz Joseph Gall （ 1758-1828 ） 推测人类的精神活动是由脑的功能活动而实现的，这才使人们认识到意识和精神活动具有物质基础，从而使人们对精神活动的认识从唯心主义的错误观点转到了唯物主义的正确轨道上来。</p><p>意大利细胞学家 Camillo Golgi （ 1843~1926 ）徒手将脑组织切成薄片，用重铬酸钾 - 硝酸银浸染法染色，第一次在显微镜下观察到了神经细胞和神经胶质细胞。这为神经科学的研究提供了最为基本的组织学方法。</p><p>西班牙神经组织学家 Santiago Ramón y Cajal （ 1852~1934 ）在掌握了 Golgi 染色法后，又进一步改良了 Golgi 染色法，并发明了独创的银染法——还原硝酸银染色法， 此法可显示神经纤维的微细结构 。他发现神经细胞之间没有原生质的联系，因而提出神经细胞是整个神经活动最基本的单位（故称神经元），从而使复杂的神经系统有了进一步研究的切入口。他对于大脑的微观结构研究是开创性的，被许多人认为是现代神经科学之父。他绘图技能出众，他的关于脑细胞的几百个插图至今用于教学。</p><p>为此，Santiago Ramón y Cajal 和 Camillo Golgi 两人共享了 1906 年诺贝尔生理学或医学奖。</p><p>此后， Cajal 经过大量精细的实验，创立了 “ 神经元学说 ” ，该学说的创立为神经科学的进一步发展开创了新纪元。</p><p>对智能机器的探索和计算机的历史一样古老。尽管中文里“电脑”一开始就拥有了“脑”的头衔，但事实上与真正的智能相去甚远。艾伦图灵在他的文章《COMPUTING MACHINERY AND INTELLIGENCE》中提出了几个标准来评估一台机器是否可以被认为是智能的，从而被称为“图灵测试”。</p><p>神经元及其连接里也许藏着智能的隐喻，沿着这条路线前进的人被称为<strong>连接主义</strong>。</p><p>1943年，Warren McCulloch 和 Walter Pitts 发表题为《A Logical Calculus of the Ideas Immanent in Nervous Activity》的论文，首次提出神经元的M-P模型。该模型借鉴了已知的神经细胞生物过程原理，是第一个神经元数学模型，是人类历史上第一次对大脑工作原理描述的尝试。</p><p><img src="https://s2.loli.net/2022/02/08/6D7UCLBGSAWj8mo.png" alt="M-P模型"></p><p>M-P模型的工作原理是神经元的<strong>输入信号加权求和</strong>，与<strong>阈值</strong>比较再决定神经元是否输出。这是从原理上证明了人工神经网络可以计算任何算术和逻辑函数。</p><p>20世纪40年代末，Donald Olding Hebb在《The Organization of Behavior》中对神经元之间连接强度的变化进行了分析，首次提出来一种调整权值的方法，称为Hebb学习规则。</p><p>Hebb学习规则主要假定机体的行为可以由神经元的行为来解释。Hebb受启发于巴普罗夫的条件反射实验，认为如果两个神经元在同一时刻被激发，则它们之间的联系应该被强化。这就是Hebb提出的生物神经元的学习机制，在这种学习中，由对神经元的重复刺激，使得神经元之间的突触强度增加。</p><p>Hebb学习规则隶属于无监督学习算法的范畴，其主要思想是根据两个神经元的激发状态来调整期连接关系，以此实现对简单神经活动的模拟。继Hebb学习规则之后，神经元的有监督Delta学习规则被提出，用于解决在输入输出已知的情况下神经元权值的学习问题。</p><p>1958年，就职于Cornell航空实验室的Frank Rosenblatt发明了的一种称为<strong>感知器</strong>（Perceptron）的人工神经网络。它可以被视为一种最简单形式的前馈神经网络，是一种<strong>二元线性分类器（激活函数为sign(x)）</strong>。感知机是人工神经网络的第一个实际应用，标志着神经网络进入了新的发展阶段。</p><p>这次成功的应用也引起了许多学者对神经网络的研究兴趣。1960年，斯坦福大学教授Bernard Widrow教授和他的研究生Ted Hoff开发了Adaline（Adaptive Linear Neuron 或  Adaptive Linear Element）和最小均方滤波器（LMS）。Adaline网络和感知机的区别就是将感知机的Step函数换为Linear线性函数。同一时期，Steinbuch等还提出了称为学习矩阵的二进制联想网络。</p><p><img src="https://s2.loli.net/2022/02/08/yTUFi5l3WO6eQcS.png" alt="Adaline和Perceptron对比"></p><p>周志华《机器学习》第5章神经网络解释了BP算法实质是LMS算法（Least Mean Square）算法的推广。LMS试图使网络的输出均方差最小化，可用于神经元激活函数可微的感知机学习；将LMS推广到由非线性可微神经元组成的多层前馈神经网络，就得到BP算法，因此BP算法也被称为广义δ规则。</p><p>1969年，Marvin Minsky 和 Seymour Papert 发表《Perceptrons: an introduction to computational geometry》一书，从数学的角度<strong>证明了单层神经网络具有有限的功能，甚至在面对简单的“异或”逻辑问题时也显得无能为力。此后，神经网络的研究陷入了很长一段时间的低迷期。</strong></p><p>1972年，芬兰的KohonenT.教授，提出了自组织神经网络SOM(Self-Organizing feature map)。</p><p>1974 年，Paul Werbos在哈佛大学攻读博士学位期间，就在其博士论文中发明了影响深远的著名<strong>BP神经网络学习算法</strong>。但没有引起重视。</p><p>1976年，美国Grossberg教授提出了著名的自适应共振理论ART(Adaptive Resonance Theory)，其学习过程具有自组织和自稳定的特征。</p><p>1982年，David Parker<strong>重新发现了BP神经网络学习算法</strong>。</p><p>1982年，John Hopfield提出了连续和离散的Hopfield神经网络模型，并采用全互联型神经网络尝试对非多项式复杂度的旅行商问题进行了求解，促进神经网络的研究再次进入了蓬勃发展的时期。</p><p>1983年，Hinton, G. E. 和 Sejnowski, T. J.设计了玻尔兹曼机，<strong>首次提出了“隐单元”的概念。在全连接的反馈神经网络中，包含了可见层和一个隐层，这就是玻尔兹曼机。</strong></p><p><strong>层数的增加可以为神经网络提供更大的灵活性，但参数的训练算法一直是制约多层神经网络发展的一个重要瓶颈。</strong></p><p>一个沉睡十年的伟大算法即将被唤醒。</p><p>1986年，David E. Rumelhart, Geoffrey E. Hinton 和 Ronald J. Williams发表文章《Learning representations by back-propagating errors》，重新报道这一方法，<strong>BP神经网络学习算法</strong>才受到重视。BP算法引入了可微分非线性神经元或者sigmod函数神经元，克服了早期神经元的弱点，为多层神经网络的学习训练与实现提供了一种切实可行的解决途径。</p><p>1988年，继BP算法之后，David Broomhead 和 David Lowe 将径向基函数引入到神经网络的设计中，形成了径向基神经网络（RBF）。RBF网络是神经网络真正走向实用化的一个重要标志。</p><p>1989年，一系列文章对BP神经网络的非线性函数逼近性能进行了分析，并证明对于具有单隐层，传递函数为sigmod的连续型前馈神经网络可以以任意精度逼近任意复杂的连续映射。这样，BP神经网络凭借能够保证对复杂函数连续映射关系的刻画能力（只要引入隐层神经元的个数足够多），打开了Marvin Minsky 和 Seymour Papert 早已关闭的研究大门。</p><p>统计学习理论是一种专门研究小样本情况下机器学习规律的理论。Vapnik, V.N.等人从六、七十年代开始致力于此方面研究。到九十年代中期，随着其理论的不断发展和成熟，也由于神经网络等学习方法在理论上缺乏实质性进展，统计学习理论开始受到越来越广泛的重视。同时, 在这一理论基础上发展了一种新的通用学习方法——支持向量机( SVM )，它已初步表现出很多优于已有方法的性能。</p><p>此后的近十年时间，神经网络由于其浅层结构，容易过拟合以及参数训练速度慢等原因，曾经火热的神经网络又慢慢的淡出了人们的视线。值得一提的是，1997年，Sepp Hochreiter和Jurgen Schmidhuber首先提出长短期记忆（LSTM）模型。</p><p>直到2006年，计算机处理速度和存储能力大大提高，为深度学习的提出铺平了道路。G. E. Hinton 和他的学生 R. R. Salakhutdinov 在《科学》杂志上发表题为《Reducing the Dimensionality of Data with Neural Networks》的文章，掀起了深度学习在学术界和工业界的研究热潮。文章摘要阐述了两个重要观点：一是多隐层的神经网络可以学习到能刻画数据本质属性的特征，对数据可视化和分类等任务有很大帮助；二是可以借助于无监督的“逐层初始化”策略来有效克服深层神经网络在训练上存在的难度。</p><p>这篇文章是一个分水岭，拉开了深度学习大幕，标志着深度学习的诞生。从此，历史这样写就：从感知机提出，到BP算法应用以及2006年以前的历史被称为浅层学习，以后的历史被称为深度学习。</p><p>总结起来，典型的浅层学习模型包括：传统隐马尔可夫模型（HMM）、条件随机场（CRFs）、最大熵模型（MaxEnt）、boosting、支持向量机（SVM）、核回归及仅含单隐层的多层感知器（MLP）等。</p><p>同年，G. E. Hinton 又提出了深度信念网络(Deep BeliefNetwork, DBN) 。深度信念网络基于受限玻尔兹曼机构建。</p><p>限制玻尔兹曼机（RBM）是一种玻尔兹曼机的变体，但限定模型必须为二分图。模型中包含对应输入参数的输入（可见）单元和对应训练结果的隐单元，图中的每条边必须连接一个可见单元和一个隐单元。与此相对，“无限制”玻尔兹曼机(BM)包含隐单元间的边，使之成为递归神经网络。BM 由Geoffrey Hinton 和 Terry Sejnowski 在1985年发明，1986年Paul Smolensky 命名了RBM，但直到Geoffrey Hinton及其合作者在2006年左右发明快速学习算法后，受限玻兹曼机才变得知名。</p><p>自动编码器早在1986年就被Rumelhart等人提出（也有资料说第一个自动感应器是福岛神经认知机），2006年之后，G. E. Hinton 等人又对自动编码器进行改造，出现了深度自编码器，稀疏自编码器等。2008年，Pascal Vincent和 Yoshua Bengio 等人在《Extracting and composing robust features with denoising autoencoders》中提出了去噪自编码器，2010年又提出来层叠去噪自编码器。2011年，Richard Socher等人也提出了递归自编码器 (RAE)。</p><p>目前，卷积神经网络作为深度学习的一种，已经成为当前图像理解领域研究的热点。早在1989年，Yann Le Cun在贝尔实验室就开始使用卷积神经网络识别手写数字；1998年，Yann Le Cun提出了用于字符识别的卷积神经网络LeNet5，并在小规模手写数字识别中取得了较好的结果。基于这些工作，Yann Le Cun也被称为卷积网络之父。2012年，Alex Krizhevsky等使用采用卷积神经网络的AlexNet在ImageNet竞赛图像分类任务中取得了最好成绩，是卷积神经网络在图像分类中的巨大成功。随后Alex Krizhevsky.，Ilya Sutskever.和 Geoffrey Hinton.发表了文章《ImageNet Classification with Deep Convolutional Neural Networks》 。</p><p>2013年，Graves 证明，结合了长短时记忆(long short terms memory, LSTM) 的递归神经网络(recurrent neural network, RNN)比传统的递归神经网络在语音处理方面更有效。2014年至今， 深度学习在很多领域都取得了突破性进展，发展出了包括注意力(attention)，RNN–CNN， 以及深度残差网络等多种模型。</p><p>最后，给出一个神经网络发展历史的回顾总结：</p><img src="https://s2.loli.net/2022/02/08/L6tYnipbTzFkrER.png" alt="神经网络发展回顾" style="zoom:80%; display:block;margin:auto;" /> <p>人工神经网络基本上由以下组件组成：</p><ul><li><strong>输入层：</strong>接收并传递数据</li><li><strong>隐藏层</strong>（隐含层）</li><li><strong>输出层</strong></li><li>各层之间的<strong>权重</strong></li><li>每个隐藏层都有一个<strong>激活函数</strong>。</li></ul><p>我们搭建一个包含隐含层的神经网络来解决”异或“问题，所谓”异或“，就是输入两个值不同，输出为1，输入两个值相同，输出为0.</p><h2 id="excel版本实现"><a href="#excel版本实现" class="headerlink" title="excel版本实现"></a>excel版本实现</h2><img src="https://s2.loli.net/2022/02/08/Xao9YhnxBeQmWwT.png" alt="实现异或的网络结构" style="zoom:67%;display:block;margin:auto;" /><p>如上图所示的神经元（即实心圆）中，其激活函数是阶跃函数（<code>sgn</code>函数，x&gt;=0时f(x)=1,else f(x) = 0 )，假设各个神经元的阈值θ均为0.5</p><p>当x1和x2相同（假设均为1时），对于隐含层的神经元1来说，输出可以表述为</p><p><code>f1 = sgn(x1*w1 + x2*w3 - θ) = sgn(1*1 + 1*(-1) - 0.5 ) = sgn(-0.5) = 0</code></p><p>激活函数的作用体现在Excel单元格<code>E2</code>中输入的公式上</p><figure class="highlight excel"><table><tr><td class="gutter"><div class="code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><pre><code class="hljs excel">=<span class="hljs-built_in">IF</span>(<span class="hljs-symbol">C2</span>*<span class="hljs-symbol">D2</span>+<span class="hljs-symbol">C4</span>*<span class="hljs-symbol">D4</span>-<span class="hljs-symbol">D6</span>&gt;<span class="hljs-number">0</span>,<span class="hljs-number">1</span>,<span class="hljs-number">0</span>)<br></code></pre></td></tr></table></figure><p> 类似地，对于隐含层的神经元2有</p><p><code>f2 = sgn(x1*w2 + x2*w4 - θ) = sgn(1*1 + 1*(-1) - 0.5 ) = sgn(-0.5) = 0</code></p><p>激活函数的作用体现在Excel单元格<code>E4</code>中输入的公式上</p><figure class="highlight excel"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs excel">=<span class="hljs-built_in">IF</span>(<span class="hljs-symbol">C2</span>*<span class="hljs-symbol">D3</span>+<span class="hljs-symbol">C4</span>*<span class="hljs-symbol">D5</span>-<span class="hljs-symbol">D6</span>&gt;<span class="hljs-number">0</span>,<span class="hljs-number">1</span>,<span class="hljs-number">0</span>)<br></code></pre></td></tr></table></figure><p>接着对于输出层的输出神经元y而言，隐含层的f1和f2都是它的输入，于是有：</p><p><code>y =  f3 = sgn(f1*w5 + f2*w6 - θ) = sgn(0*1 + 0*1 - 0.5) = sgn(-0.5) = 0</code></p><p>对应体现在Excel单元格<code>H3</code>中输入的公式上</p><figure class="highlight excel"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs excel">=<span class="hljs-built_in">IF</span>(<span class="hljs-symbol">E2</span>*<span class="hljs-symbol">F2</span>+<span class="hljs-symbol">E4</span>*<span class="hljs-symbol">F4</span>-<span class="hljs-symbol">G6</span>&gt;<span class="hljs-number">0</span>,<span class="hljs-number">1</span>,<span class="hljs-number">0</span>)<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/08/gzJkQe62ROB1DtH.png" alt="image-20220208134520558"></p><p>如图我们可以看到其结果为0，满足<strong>异或</strong>的功能，神经网络搭建完成，剩下的就是更改输入即可，无需更改任何公式，一切都是自动更新计算的，读者可以自行尝试，我们可以感性认识到，网络层次越深，神经网络的表征能力越强。</p><p>或许你会疑惑，神经网络的权值和阈值时怎么知道的，在这个案例中我们直接给了出来，而实际上，他们是需要神经网络自己反复“试错”学习而来的，而且能完成“异或”功能的网络权重也不唯一。</p><h2 id="python版本实现"><a href="#python版本实现" class="headerlink" title="python版本实现"></a>python版本实现</h2><p>MLPClassifier是一个监督学习算法，下图是只有1个隐藏层的MLP模型 ，左侧是输入层，右侧是输出层。</p><img src="https://s2.loli.net/2022/02/08/uFc1A3Wm7j92SVO.png" alt="MLP模型" style="zoom: 50%; display:block; margin:auto;" /><p>上图的整体结构可以简单的理解为下图所示：</p><img src="https://s2.loli.net/2022/02/08/zW6XYcisfp5QHTR.png" alt="image-20220208153609189" style="zoom:67%; display:block;margin:auto;" /><p>MLP又名多层感知机，也叫人工神经网络（ANN，Artificial Neural Network），除了输入输出层，它中间可以有多个隐藏层，如果没有隐藏层即可解决线性可划分的数据问题。最简单的MLP模型只包含一个隐藏层，即三层的结构，如上图。</p><p>从上图可以看到，多层感知机的层与层之间是全连接的（全连接的意思就是：上一层的任何一个神经元与下一层的所有神经元都有连接）。多层感知机最底层是输入层，中间是隐藏层，最后是输出层。</p><p>输入层没什么好说，你输入什么就是什么，比如输入是一个n维向量，就有n个神经元。</p><p>隐藏层的神经元怎么得来？首先它与输入层是全连接的，假设输入层用向量X表示，则隐藏层的输出就是</p><p>f(W1X+b1)，W1是权重（也叫连接系数），b1是偏置，函数f 可以是常用的激活函数如 sigmoid函数或者tanh函数</p><p>最后就是输出层，输出层与隐藏层是什么关系？其实隐藏层到输出层可以看成是一个多类别的逻辑回归，也即softmax回归，所以输出层的输出就是softmax(W2X1+b2)，X1表示隐藏层的输出f(W1X+b1)。</p><p>因此，MLP所有的参数就是各个层之间的连接权重以及偏置，包括W1、b1、W2、b2。对于一个具体的问题，怎么确定这些参数？求解最佳的参数是一个最优化问题，解决最优化问题，最简单的就是梯度下降法了（sgd）：首先随机初始化所有参数，然后迭代地训练，不断地计算梯度和更新参数，直到满足某个条件为止（比如误差足够小、迭代次数足够多时）。这个过程涉及到代价函数、规则化（Regularization）、学习速率（learning rate）、梯度计算等。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment">#!/usr/bin/env python3</span><br><span class="hljs-comment"># -*- coding: utf-8 -*-</span><br><br><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np<br><span class="hljs-comment"># （1）导入模型</span><br><span class="hljs-keyword">from</span> sklearn.neural_network <span class="hljs-keyword">import</span> MLPClassifier<br><br><span class="hljs-comment"># （2）方案1：创建多层感知机分类器:注意，此时激活函数使用relu或tanh和solver（默认的adam）匹配</span><br><span class="hljs-comment"># model = MLPClassifier(hidden_layer_sizes=(4,2,), activation=&#x27;tanh&#x27;,</span><br><span class="hljs-comment">#                     max_iter = 10000)</span><br><br><span class="hljs-comment"># 方案2：不同的激活函数，使用不同的solver，需要不断尝试</span><br><span class="hljs-comment"># default = &#x27;adam&#x27; and works well for large data sets.</span><br><br>model = MLPClassifier(activation=<span class="hljs-string">&#x27;logistic&#x27;</span>, max_iter=<span class="hljs-number">1000</span>,<br>                      hidden_layer_sizes=(<span class="hljs-number">3</span>,),<br>                      solver=<span class="hljs-string">&#x27;lbfgs&#x27;</span>)<br><br><span class="hljs-comment"># （3）构造所需训练数据</span><br>X = np.array([[<span class="hljs-number">1</span>, <span class="hljs-number">1</span>],<br>              [<span class="hljs-number">0</span>, <span class="hljs-number">0</span>],<br>              [<span class="hljs-number">1</span>, <span class="hljs-number">0</span>],<br>              [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>]])<br>y = np.array([<span class="hljs-number">0</span>,<br>              <span class="hljs-number">0</span>,<br>              <span class="hljs-number">1</span>,<br>              <span class="hljs-number">1</span>])<br><br><span class="hljs-comment"># （4）训练模型</span><br>model.fit(X, y)<br><br><span class="hljs-comment"># （5）模型预测</span><br><span class="hljs-built_in">print</span>(<span class="hljs-string">&#x27;1 xor 1 = %d&#x27;</span> % model.predict([[<span class="hljs-number">1</span>, <span class="hljs-number">1</span>]]))<br><span class="hljs-built_in">print</span>(<span class="hljs-string">&#x27;0 xor 0 = %d&#x27;</span> % model.predict([[<span class="hljs-number">0</span>, <span class="hljs-number">0</span>]]))<br><span class="hljs-built_in">print</span>(<span class="hljs-string">&#x27;1 xor 0 = %d&#x27;</span> % model.predict([[<span class="hljs-number">1</span>, <span class="hljs-number">0</span>]]))<br><span class="hljs-built_in">print</span>(<span class="hljs-string">&#x27;0 xor 1 = %d&#x27;</span> % model.predict([[<span class="hljs-number">0</span>, <span class="hljs-number">1</span>]]))<br></code></pre></td></tr></table></figure><p>输出结果：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-number">1</span> xor <span class="hljs-number">1</span> = <span class="hljs-number">0</span><br><span class="hljs-number">0</span> xor <span class="hljs-number">0</span> = <span class="hljs-number">0</span><br><span class="hljs-number">1</span> xor <span class="hljs-number">0</span> = <span class="hljs-number">1</span><br><span class="hljs-number">0</span> xor <span class="hljs-number">1</span> = <span class="hljs-number">1</span><br></code></pre></td></tr></table></figure><p><code>MLPClassifier</code>参数说明：</p><p>activation:激活函数</p><p>max_iter：int 最大迭代次数默认200</p><p>例如hidden_layer_sizes=(50, 50)，表示有两层隐藏层，第一层隐藏层有50个神经元，第二层也有50个神经元。</p><p>solver用来优化权重    lbfgs：quasi-Newton方法的优化器</p><h2 id="练习题"><a href="#练习题" class="headerlink" title="练习题"></a>练习题</h2><p>编程实现：通过如下数据集，预测输入[1, 1, 0]的输出</p><table><thead><tr><th align="center">样本编号</th><th align="center">输入</th><th align="center">输出</th><th align="center">样本编号</th><th align="center">输入</th><th align="center">输出</th></tr></thead><tbody><tr><td align="center">样本1</td><td align="center">0 0 1</td><td align="center">0</td><td align="center">样本5</td><td align="center">1 0 0</td><td align="center">0</td></tr><tr><td align="center">样本2</td><td align="center">0 1 1</td><td align="center">1</td><td align="center">样本6</td><td align="center">1 1 1</td><td align="center">0</td></tr><tr><td align="center">样本3</td><td align="center">1 0 1</td><td align="center">1</td><td align="center">样本7</td><td align="center">0 0 0</td><td align="center">0</td></tr><tr><td align="center">样本4</td><td align="center">0 1 0</td><td align="center">1</td><td align="center">新样本</td><td align="center">1 1 0</td><td align="center">？</td></tr></tbody></table><p>代码实现：</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment"># -*- coding: utf-8 -*-</span><br><br><span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np<br><br><span class="hljs-comment">#（1）导入模型</span><br><span class="hljs-keyword">from</span> sklearn.neural_network <span class="hljs-keyword">import</span> MLPClassifier<br><br><span class="hljs-comment">#（2）方案1：创建多层感知机分类器:注意，此时激活函数使用relu或tanh和solver（默认的adam）匹配</span><br>model = MLPClassifier(hidden_layer_sizes=(<span class="hljs-number">4</span>,<span class="hljs-number">4</span>), activation=<span class="hljs-string">&#x27;relu&#x27;</span>, <br>                    max_iter = <span class="hljs-number">10000</span>)<br><br><span class="hljs-comment">#方案2：不同的激活函数，使用不同的solver，需要不断尝试</span><br><span class="hljs-comment"># default = &#x27;adam&#x27; and works well for large data sets.  </span><br><span class="hljs-comment"># model = MLPClassifier(activation=&#x27;logistic&#x27;, max_iter=10000, </span><br><span class="hljs-comment">#               hidden_layer_sizes=(4,),</span><br><span class="hljs-comment">#               solver=&#x27;lbfgs&#x27;)</span><br><br><span class="hljs-comment">#（3）构造所需训练数据</span><br>X = np.array([[<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>], <br>              [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">1</span>], <br>              [<span class="hljs-number">1</span>, <span class="hljs-number">0</span>, <span class="hljs-number">1</span>], <br>              [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>, <span class="hljs-number">0</span>], <br>              [<span class="hljs-number">1</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>], <br>              [<span class="hljs-number">1</span>, <span class="hljs-number">1</span>, <span class="hljs-number">1</span>], <br>              [<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>]])<br>y = np.array([ <span class="hljs-number">0</span>, <br>              <span class="hljs-number">1</span>, <br>              <span class="hljs-number">1</span>, <br>              <span class="hljs-number">1</span>, <br>              <span class="hljs-number">1</span>, <br>              <span class="hljs-number">0</span>, <br>              <span class="hljs-number">0</span>])<br><span class="hljs-comment">#（4）训练模型</span><br>model.fit(X, y)<br><br><span class="hljs-comment">#（4）模型预测</span><br><span class="hljs-built_in">print</span> (<span class="hljs-string">&#x27;[1，1，0] = %d&#x27;</span> % model.predict([[<span class="hljs-number">1</span>, <span class="hljs-number">1</span>, <span class="hljs-number">0</span>]]))<br><br><span class="hljs-comment">#(5)输出结果</span><br><span class="hljs-string">&#x27;&#x27;&#x27;</span><br><span class="hljs-string">[1，1，0] = 0</span><br><span class="hljs-string">&#x27;&#x27;&#x27;</span><br></code></pre></td></tr></table></figure><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><p><a href="https://www.jianshu.com/p/8aacc7f201f2">神经网络简史 - 简书 (jianshu.com)</a></p><p><a href="https://www.jiqizhixin.com/articles/2018-12-13-3">手把手教你用Python创建简单的神经网络（附代码） | 机器之心 (jiqizhixin.com)</a></p><p>人工智能极简入门-张玉宏著<a href="https://www.zhihu.com/people/yulaiyuhong">(12 封私信 / 80 条消息) 玉来愈宏 - 知乎 (zhihu.com)</a></p><p><a href="https://www.jianshu.com/p/71fde5d90136">sklearn 神经网络 MLPClassifier简单应用与参数说明 - 简书 (jianshu.com)</a></p>]]></content>
    
    
    <categories>
      
      <category>人工智能</category>
      
    </categories>
    
    
    <tags>
      
      <tag>神经网络</tag>
      
      <tag>人工智能</tag>
      
      <tag>机器学习</tag>
      
    </tags>
    
  </entry>
  
  
  
  <entry>
    <title>Cypher语句从入门到上天</title>
    <link href="/2022/02/02/Cypher%E8%AF%AD%E5%8F%A5%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E4%B8%8A%E5%A4%A9/"/>
    <url>/2022/02/02/Cypher%E8%AF%AD%E5%8F%A5%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E4%B8%8A%E5%A4%A9/</url>
    
    <content type="html"><![CDATA[<h1 id="cypher语句大全"><a href="#cypher语句大全" class="headerlink" title="cypher语句大全"></a>cypher语句大全</h1><h2 id="下载和安装"><a href="#下载和安装" class="headerlink" title="下载和安装"></a><strong>下载和安装</strong></h2><p><a href="https://www.w3cschool.cn/neo4j/">neo4j 教程_w3cschool</a></p><p>Neo4j windows 桌面版 下载地址：<a href="https://neo4j.com/download/?ref=get-started-dropdown-cta">Neo4j Desktop Download | Free Graph Database Download</a></p><p>Cypher语言的关键字不区分大小写，但是属性值，标签，关系类型和变量是区分大小写的。</p><p>Neo4j中不存在表的概念，只有**标签(labels),节点(Node),关联(Relation),路径(path)**，标签里存的节点,节点和关联可以简单理解为图里面的点和边,路径是用节点和关联表示的如：(a)-[r]-&gt;(b)，表示一条从节点a经关联r到节点b的路径。</p><p>在数据查询中，节点一般用**小括号()，关联用中括号[]**。</p><span id="more"></span><p><strong>关于Neo4j和Cypher批量更新和批量插入优化的5个建议</strong></p><p><a href="https://blog.csdn.net/hwz2311245/article/details/60963383"><strong>https://blog.csdn.net/hwz2311245/article/details/60963383</strong></a></p><p><strong>Neo4j之Cypher学习总结</strong></p><p><a href="https://www.jianshu.com/p/2bb98c81d8ee"><strong>https://www.jianshu.com/p/2bb98c81d8ee</strong></a></p><h2 id="常用cypher语句"><a href="#常用cypher语句" class="headerlink" title="常用cypher语句"></a>常用cypher语句</h2><p><strong>快速清空数据库</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><div class="code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><pre><code class="hljs cypher">match (n) detach delete n<br></code></pre></td></tr></table></figure><p><strong>创造一个节点</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">create (n:Person &#123;name:&quot;我&quot;, age:21&#125;)<br></code></pre></td></tr></table></figure><p><strong>创建关系</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">create (p:Person &#123;name:&quot;我&quot;, age:&quot;23&quot;&#125;)-[:包工程&#123;金额:10000&#125;]-&gt;(n:Person &#123;name:&quot;好大哥&quot;, age:&quot;35&quot;&#125;)<br></code></pre></td></tr></table></figure><p> <strong>删除节点</strong>    注意 删除有连接的节点时  必须先删掉关系  </p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs cypher">create (n:Person &#123;name:&quot;XL&quot;, age:23&#125;)<br>match (n:Person &#123;name:&quot;XL&quot;&#125;) delete n<br></code></pre></td></tr></table></figure><p><strong>删除关系</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match (p:Person &#123;name:&quot;我&quot;, age:&quot;23&quot;&#125;)-[f:包工程&#123;金额:10000&#125;]-&gt;(n:Person &#123;name:&quot;好大哥&quot;, age:&quot;35&quot;&#125;) delete f<br></code></pre></td></tr></table></figure><p><strong>加上标签</strong></p><p>同个某个节点的id   找到它   然后给其设置一个好人的标签</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match (t:Person) where id(t)=2 set t:好人 return t<br></code></pre></td></tr></table></figure><p><strong>额外增加属性</strong></p><p>在好人标签中找一个节点的id为2  然后给其加一个战斗力属性  并设置其值为200</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match (a:好人) where id(a)=2 set a.战斗力=200 return a<br></code></pre></td></tr></table></figure><p><strong>查找</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs cypher">create (:Person &#123;name:&quot;唐僧&quot;, age:&quot;79&quot;&#125;)-[:师傅 &#123;s_time:&quot;2020-11-23&quot;&#125;]-&gt;(:Person &#123;name:&quot;孙悟空&quot;, age:&quot;1w&quot;&#125;)<br>match (a:Person)-[:师傅]-&gt;(b:Person) return a,b<br></code></pre></td></tr></table></figure><p><strong>显示所有节点关系</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match (n) return n<br></code></pre></td></tr></table></figure><p><strong>删除节点关系</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (a:Person) OPTIONAL MATCH (a)-[r1]-() DELETE a, r1<br></code></pre></td></tr></table></figure><p><strong>查找人员</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (tom &#123;name: &quot;Tom Hanks&quot;&#125;) RETURN tom<br></code></pre></td></tr></table></figure><h2 id="1-创建节点"><a href="#1-创建节点" class="headerlink" title="1.创建节点"></a><strong>1.创建节点</strong></h2><p>创建Person 标签,刘德华等若干节点,各自有name,birthday ,born,englishname等属性</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs cypher">create (n:Person &#123; name: &#x27;朱丽倩&#x27;, birthday:&#x27;1966年4月6日&#x27;,born: 1966 ,englishname:&#x27;Carol&#x27;&#125;);<br>create (n:Person &#123; name: &#x27;刘向蕙&#x27;, birthday:&#x27;2012年5月9日&#x27;,born: 2012 ,englishname:&#x27;Hanna&#x27;&#125;);<br>create (n:Person &#123; name: &#x27;任贤齐&#x27;, birthday:&#x27;1966年6月23日&#x27;,born: 1966 ,englishname:&#x27;Richie Jen&#x27;&#125;);<br>create (n:Person &#123; name: &#x27;金城武&#x27;, birthday:&#x27;1973年10月11日&#x27;,born: 1973,englishname:&#x27;Takeshi Kaneshiro&#x27;&#125;);<br>create (n:Person &#123; name: &#x27;林志玲&#x27;, birthday:&#x27;1974年11月29日&#x27;,born: 1974,englishname:&#x27;zhilin&#x27;&#125;);<br>create (n:Person &#123; name: &#x27;刘德华&#x27;, birthday:&#x27;1961年9月27日&#x27;,born: 1961,englishname:&#x27;Andy Lau&#x27;&#125;);<br></code></pre></td></tr></table></figure><p>创建Movie 标签,彩云曲等若干节点,各自有title,released 等属性</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs cypher">create (n:Movie &#123; title: &#x27;彩云曲&#x27;,released: 1981&#125;);<br>create (n:Movie &#123; title: &#x27;神雕侠侣&#x27;,released: 1983&#125;);<br>create (n:Movie &#123; title: &#x27;暗战&#x27;,released: 2000&#125;);<br>create (n:Movie &#123; title: &#x27;拆弹专家&#x27;,released: 2017&#125;);<br></code></pre></td></tr></table></figure><h2 id="2-查询节点"><a href="#2-查询节点" class="headerlink" title="2.查询节点"></a><strong>2.查询节点</strong></h2><h3 id="2-1-查询整个图形数据库"><a href="#2-1-查询整个图形数据库" class="headerlink" title="2.1 查询整个图形数据库:"></a><strong>2.1 查询整个图形数据库:</strong></h3><p>点击节点，查看节点的属性，如图，Neo4j自动为节点设置ID值 </p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match(n) return n;<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/Bu7n5cQGeFzNoxV.png" alt="image-20220202110925533"></p><h3 id="2-2-查询具有指定标签的节点"><a href="#2-2-查询具有指定标签的节点" class="headerlink" title="2.2 查询具有指定标签的节点"></a><strong>2.2 查询具有指定标签的节点</strong></h3><p>查询Movie标签下的节点</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match(n:Movie) return n;  <br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/txEYNlFX62jJvDy.png" alt="image-20220202111032896"></p><h3 id="2-3-where-谓词查询"><a href="#2-3-where-谓词查询" class="headerlink" title="2.3 where 谓词查询"></a><strong>2.3 where</strong> <strong>谓词查询</strong></h3><p>查询名称为林志玲的节点</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match (n:Person) where n.name=&#x27;林志玲&#x27; return n<br></code></pre></td></tr></table></figure><p>**(查询具有指定属性的节点)**结果相同</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match(n&#123;name:&#x27;林志玲&#x27;&#125;) return n;<br></code></pre></td></tr></table></figure><p>查询born属性小于1967的节点 </p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match(n) where n.born&lt;1967 return n; <br></code></pre></td></tr></table></figure><h2 id="3-创建关系"><a href="#3-创建关系" class="headerlink" title="3.创建关系"></a><strong>3.创建关系</strong></h2><p>关系的构成：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">StartNode - [Variable:RelationshipType&#123;Key1:Value1,Key2:Value2&#125;] -&gt; EndNode<br></code></pre></td></tr></table></figure><p>在创建关系时，必须指定关系类型。</p><h3 id="3-1-创建没有任何属性的关系"><a href="#3-1-创建没有任何属性的关系" class="headerlink" title="3.1 创建没有任何属性的关系"></a><strong>3.1 创建没有任何属性的关系</strong></h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (a:Person),(b:Movie)<br>WHERE a.name = &#x27;刘德华&#x27; AND b.title = &#x27;暗战&#x27;<br>CREATE (a)-[r:DIRECTED]-&gt;(b)<br>RETURN r;<br></code></pre></td></tr></table></figure><p>得到结果：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs json">&#123;<br>  <span class="hljs-attr">&quot;identity&quot;</span>: <span class="hljs-number">2</span>,<br>  <span class="hljs-attr">&quot;start&quot;</span>: <span class="hljs-number">9</span>,<br>  <span class="hljs-attr">&quot;end&quot;</span>: <span class="hljs-number">7</span>,<br>  <span class="hljs-attr">&quot;type&quot;</span>: <span class="hljs-string">&quot;DIRECTED&quot;</span>,<br>  <span class="hljs-attr">&quot;properties&quot;</span>: &#123;<br><br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/DLJSuTd6yRVBcli.png" alt="image-20220203101836271"></p><h3 id="3-2-创建关系，并设置关系的属性"><a href="#3-2-创建关系，并设置关系的属性" class="headerlink" title="3.2 创建关系，并设置关系的属性"></a><strong>3.2 创建关系，并设置关系的属性</strong></h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (a:Person),(b:Movie)<br>WHERE a.name = &#x27;刘德华&#x27; AND b.title = &#x27;神雕侠侣&#x27;<br>CREATE (a)-[r:出演 &#123; roles:[&#x27;杨过&#x27;] &#125;]-&gt;(b)<br>RETURN r;<br></code></pre></td></tr></table></figure><p>得到结果：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs json">&#123;<br>  <span class="hljs-attr">&quot;identity&quot;</span>: <span class="hljs-number">1</span>,<br>  <span class="hljs-attr">&quot;start&quot;</span>: <span class="hljs-number">9</span>,<br>  <span class="hljs-attr">&quot;end&quot;</span>: <span class="hljs-number">6</span>,<br>  <span class="hljs-attr">&quot;type&quot;</span>: <span class="hljs-string">&quot;出演&quot;</span>,<br>  <span class="hljs-attr">&quot;properties&quot;</span>: &#123;<br><span class="hljs-attr">&quot;roles&quot;</span>: [<br>      <span class="hljs-string">&quot;杨过&quot;</span><br>    ]<br>  &#125;<br>&#125;<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/i4L2GhUzAkvjaOc.png" alt="image-20220203100212404"></p><h3 id="3-3-创建双向关系"><a href="#3-3-创建双向关系" class="headerlink" title="3.3 创建双向关系"></a><strong>3.3 创建双向关系</strong></h3><p>刘德华的女是刘向蕙,刘向蕙的父亲是刘德华</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (a:Person),(c:Person)<br>WHERE a.name = &#x27;刘德华&#x27; AND c.name = &#x27;刘向蕙&#x27;<br>CREATE (a)-[r:父亲 &#123; nickname:&#x27;甜心&#x27; &#125;]-&gt;(c),<br>(c)-[d:女儿 &#123; nickname:&#x27;爹地&#x27; &#125;]-&gt;(a)<br>RETURN r;<br></code></pre></td></tr></table></figure><p>关系建错了  删除关系 (见<strong>5.2</strong> )</p><p>重新创建</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (a:Person),(c:Person)<br>WHERE a.name = &#x27;刘德华&#x27; AND c.name = &#x27;刘向蕙&#x27;<br>CREATE (a)-[d:女儿 &#123; nickname:&#x27;甜心&#x27; &#125;]-&gt;(c),<br>(c)-[r:父亲 &#123; nickname:&#x27;爹地&#x27; &#125;]-&gt;(a)<br>RETURN r;<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/YavpdHserRAy4mW.png" alt="image-20220203102036130"></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (a:Person),(c:Movie)<br>WHERE a.name = &#x27;刘德华&#x27; AND c.title = &#x27;彩云曲&#x27;<br>CREATE (a)-[r:出演 &#123; partner:&#x27;张国荣&#x27; &#125;]-&gt;(c),<br>(c)-[d:演员 &#123; rolename:&#x27;阿华哥&#x27; &#125;]-&gt;(a)<br>RETURN r;<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/kwvpDYWjxlnMAJC.png" alt="image-20220203102237935"></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (a:Person),(c:Movie)<br>WHERE a.name = &#x27;刘德华&#x27; AND c.title = &#x27;拆弹专家&#x27;<br>CREATE (a)-[r:出演 &#123; partner:&#x27;赵薇,高圆圆&#x27; &#125;]-&gt;(c),<br>(c)-[d:演员 &#123; rolename:&#x27;华仔&#x27; &#125;]-&gt;(a)<br>RETURN r;<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/YyOjUJkwfoRrZxM.png" alt="image-20220203102402590"></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (a:Person),(c:Movie)<br>WHERE a.name = &#x27;刘德华&#x27; AND c.title = &#x27;神雕侠侣&#x27;<br>CREATE (a)-[r:出演 &#123; partner:&#x27;刘亦菲&#x27; &#125;]-&gt;(c),<br>(c)-[d:演员 &#123; rolename:&#x27;杨过&#x27; &#125;]-&gt;(a)<br>RETURN r;<br></code></pre></td></tr></table></figure><p>继续新增关系  刘德华和林志玲,金城武,任贤齐</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (a:Person),(c:Person)<br>WHERE a.name = &#x27;刘德华&#x27; AND c.name = &#x27;任贤齐&#x27;<br>CREATE (a)-[d:朋友 &#123; sex:&#x27;男&#x27; &#125;]-&gt;(c)<br>RETURN d;<br><br>MATCH (a:Person),(c:Person)<br>WHERE a.name = &#x27;刘德华&#x27; AND c.name = &#x27;金城武&#x27;<br>CREATE (a)-[d:朋友 &#123; sex:&#x27;男&#x27; &#125;]-&gt;(c)<br>RETURN d;<br></code></pre></td></tr></table></figure><p> 下面这个没有给关系设置属性sex</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (a:Person),(c:Person)<br>WHERE a.name = &#x27;刘德华&#x27; AND c.name = &#x27;林志玲&#x27;<br>CREATE (a)-[d:朋友]-&gt;(c)<br>RETURN d;          <br></code></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match (a:Person), (b:Person) <br>where a.name=&quot;刘德华&quot; and b.name=&quot;朱丽倩&quot;<br>create (a)-[c:wife]-&gt;(b)<br>return c;<br></code></pre></td></tr></table></figure><p>查询Person表关系</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (n:Person) RETURN n<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/xG1nWKAfVhZUSbt.png" alt="image-20220203103532784">    </p><h2 id="4-查询关系"><a href="#4-查询关系" class="headerlink" title="4 查询关系"></a><strong>4 查询关系</strong></h2><p>在Cypher中，关系分为三种：符号“–”，表示有关系，忽略关系的类型和方向；符号“–&gt;”和“&lt;–”，表示有方向的关系；</p><h3 id="4-1-查询整个数据图形"><a href="#4-1-查询整个数据图形" class="headerlink" title="4.1 查询整个数据图形"></a><strong>4.1 查询整个数据图形</strong></h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match (n) return n;<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/SgaheU1cTzm8r9k.png" alt="image-20220203103717979"></p><h3 id="4-2-查询跟指定节点有关系的节点"><a href="#4-2-查询跟指定节点有关系的节点" class="headerlink" title="4.2 查询跟指定节点有关系的节点"></a><strong>4.2 查询跟指定节点有关系的节点</strong></h3><p>查询跟Movie标签有关系的所有节点</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match (n) -- (m:Movie) return n;<br></code></pre></td></tr></table></figure><h3 id="4-3-查询有向关系的节点"><a href="#4-3-查询有向关系的节点" class="headerlink" title="4.3 查询有向关系的节点"></a><strong>4.3 查询有向关系的节点</strong></h3><p>查询和刘德华有关系的电影</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (:Person &#123; name: &#x27;刘德华&#x27; &#125;)--&gt;(movie:Movie) RETURN movie;<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/vfBJL3xPmqyW7Sa.png" alt="image-20220203104152249"></p><h3 id="4-4-为关系命名"><a href="#4-4-为关系命名" class="headerlink" title="4.4  为关系命名"></a>4.4  为关系命名</h3><p><strong>通过[r]为关系定义一个变量名，通过函数type获取关系的类型</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (:Person &#123; name: &#x27;刘德华&#x27; &#125;)-[r]-&gt;(:Movie) RETURN r,type(r);<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/MozTqZQLaX6v9yY.png" alt="image-20220203104533629"></p><h3 id="4-5-查询特定的关系类型"><a href="#4-5-查询特定的关系类型" class="headerlink" title="4.5 查询特定的关系类型"></a>4.5 查询特定的关系类型</h3><p><strong>通过[Variable:RelationshipType{Key:Value}]指定关系的类型和属性</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (:Person &#123; name: &#x27;刘德华&#x27; &#125;)-[r:出演&#123;partner:&#x27;张国荣&#x27;&#125;]-&gt;(:Movie) RETURN r,type(r);<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/dXoCYZw4lH2Ef9N.png" alt="image-20220203105741475"></p><p>查询 刘德华和张国荣合作过的电影</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (:Person &#123; name: &#x27;刘德华&#x27; &#125;)-[r:出演&#123;partner:&#x27;张国荣&#x27;&#125;]-&gt;(m:Movie) RETURN m;<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/U2HgCf6Xm7u9Fri.png" alt="image-20220203105853390"></p><p>查询被刘德华称呼为甜心的女儿</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (:Person &#123; name: &#x27;刘德华&#x27; &#125;)-[r:女儿&#123;nickname:&#x27;甜心&#x27;&#125;]-&gt;(m:Person) return m<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/bXeZQ86TjsrxBAC.png" alt="image-20220203110032549"></p><p>查询刘德华的老婆是谁</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match (n:Person&#123;name: &#x27;刘德华&#x27;&#125;)-[:wife]-&gt;(a:Person) return a<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/jyHaSQF4ILCwRD2.png" alt="image-20220203110201732"></p><p>刘德华出演过的电影</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match (:Person&#123;name:&#x27;刘德华&#x27;&#125;)-[r:`出演`]-&gt;(a:Movie) return a<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/459SoWgJyBxRM6f.png" alt="image-20220203110423523"></p><h2 id="5-删除"><a href="#5-删除" class="headerlink" title="5 删除"></a><strong>5 删除</strong></h2><h3 id="5-1-删除节点"><a href="#5-1-删除节点" class="headerlink" title="5.1 删除节点"></a><strong>5.1 删除节点</strong></h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">create (n:City &#123; name: &#x27;北京&#x27;&#125;)<br></code></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match (n:City&#123;name:&#x27;北京&#x27;&#125;) delete n<br></code></pre></td></tr></table></figure><h3 id="5-2-删除关系"><a href="#5-2-删除关系" class="headerlink" title="5.2 删除关系"></a><strong>5.2 删除关系</strong></h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match (a:Person&#123;name:&#x27;刘德华&#x27;&#125;)-[r:父亲]-&gt;(b:Person&#123;name:&#x27;刘向蕙&#x27;&#125;) delete  r<br></code></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match (a:Person&#123;name:&#x27;刘向蕙&#x27;&#125;)-[r:女儿]-&gt;(b:Person&#123;name:&#x27;刘德华&#x27;&#125;) delete  r<br></code></pre></td></tr></table></figure><h3 id="5-4-强制删除节点和关系"><a href="#5-4-强制删除节点和关系" class="headerlink" title="5.4 强制删除节点和关系"></a><strong>5.4 强制删除节点和关系</strong></h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match  (n:`美国军事基地`) where n.name =&#x27;挂载&#x27;  detach delete n<br></code></pre></td></tr></table></figure><h2 id="6-常用查询关键词"><a href="#6-常用查询关键词" class="headerlink" title="6 常用查询关键词"></a><strong>6 常用查询关键词</strong></h2><h3 id="6-1-count"><a href="#6-1-count" class="headerlink" title="6.1 count"></a><strong>6.1 count</strong></h3><p>查询Person 一共有多少人</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match (n:Person ) return count(n)<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/7CQhi1WDxgd3vo4.png" alt="image-20220203111153234"></p><p>查询标签(Person)中born=1966的一共有多少节点（人）： </p><p>两种写法：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match (n:Person) where  n.born=1966   return  count(n) <br></code></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match (n:Person&#123;born:1966&#125;)  return  count(n)  //特别注意类型,如果存的类似是数字类型,使用字符串就查不出来<br></code></pre></td></tr></table></figure><h3 id="6-2-Limit-限制查询条数"><a href="#6-2-Limit-限制查询条数" class="headerlink" title="6.2 Limit 限制查询条数"></a><strong>6.2 Limit 限制查询条数</strong></h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match (n:Person) return n limit 3<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/MIfnZu3qNz6mSgl.png" alt="image-20220203111530535"></p><p><img src="https://s2.loli.net/2022/02/03/1R2ViCrJTX7SGo8.png" alt="image-20220203111556143"></p><h3 id="6-3-Distinct"><a href="#6-3-Distinct" class="headerlink" title="6.3 Distinct"></a><strong>6.3 Distinct</strong></h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match (n:Person) return  distinct(n.born)![0]<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/Dux8POUrn21KfMY.png" alt="image-20220203111927386"></p><h3 id="6-4-Order-by"><a href="#6-4-Order-by" class="headerlink" title="6.4 Order by"></a><strong>6.4 Order by</strong></h3><p>默认升序：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match(n:Person) return n order by n.born<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/SN23nMdjW7BZbCA.png" alt="image-20220203112225444"></p><p>升序：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match(n:Person) return n order by n.born asc <br></code></pre></td></tr></table></figure><p>降序：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match(n:Person) return n order by n.born desc<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/AGU9lc2Et65xHnW.png" alt="image-20220203112344584"></p><h3 id="6-5-根据id查找"><a href="#6-5-根据id查找" class="headerlink" title="6.5 根据id查找"></a><strong>6.5 根据id查找</strong></h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match (n) where id(n)=9 return n<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/2Pjig78sUwhrz63.png" alt="image-20220203112558387"></p><h3 id="6-6-In的用法"><a href="#6-6-In的用法" class="headerlink" title="6.6 In的用法"></a><strong>6.6 In的用法</strong></h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match (n) where ID(n) IN[353,145,547] return n<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/mAUQcC4lEjGxh8F.png" alt="image-20220203113259200"></p><h3 id="6-7-Exists"><a href="#6-7-Exists" class="headerlink" title="6.7 Exists"></a><strong>6.7 Exists</strong></h3><p>节点存在 name这个属性的记录：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match (n) where exists(n.title) return n<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/SA5os9HZB6UlvT8.png" alt="image-20220203113429708"></p><h3 id="6-8-With"><a href="#6-8-With" class="headerlink" title="6.8 With"></a><strong>6.8 With</strong></h3><p>查询name以‘刘’开头的节点：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match (n) where n.name starts with &#x27;刘&#x27; return n<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/98hXYdGVkucFKTn.png" alt="image-20220203113542424"></p><p>查询name以‘明’结尾的节点：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match (n) where n.name ends with &#x27;齐&#x27; return n<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/4WH7zhjsgvRpKuE.png" alt="image-20220203113641533"></p><h3 id="6-9-Contains"><a href="#6-9-Contains" class="headerlink" title="6.9 Contains"></a><strong>6.9 Contains</strong></h3><p>查询title中含有 ‘侠侣’的节点</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match (n:Movie) where n.title Contains &#x27;侠侣&#x27; return n<br></code></pre></td></tr></table></figure><h3 id="6-10-Union-all-Union"><a href="#6-10-Union-all-Union" class="headerlink" title="6.10 Union all (Union)"></a><img src="https://s2.loli.net/2022/02/03/w5palPy1YgTfkxS.png" alt="image-20220203113806845"><strong>6.10 Union all (Union)</strong></h3><p>求并集，不去重（去重用Union, as 取别名）:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match(n:Person) where n.born=1966 return n.name as name<br>Union all<br>Match(n:Movie) where n.released=1983 return n.title as name<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/I3DfJ6msNTGLYZb.png" alt="image-20220203113949112"></p><h2 id="7-更新"><a href="#7-更新" class="headerlink" title="7. 更新"></a><strong>7. 更新</strong></h2><h3 id="7-1-创建一个完整的Path"><a href="#7-1-创建一个完整的Path" class="headerlink" title="7.1 创建一个完整的Path"></a><strong>7.1 创建一个完整的Path</strong></h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs cypher">CREATE p =(m:Person&#123; name:&#x27;刘亦菲&#x27;,title:&quot;演员&quot; &#125;)-[:签约]-&gt;(neo)&lt;-[:签约]-(n:Person &#123; name: &#x27;赵薇&#x27;,title:&quot;投资人&quot; &#125;)<br>RETURN p<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/uhiIdG9JtHSvnoW.png" alt="image-20220203115659660"></p><h3 id="7-2-为节点增加一个属性"><a href="#7-2-为节点增加一个属性" class="headerlink" title="7.2 为节点增加一个属性"></a><strong>7.2 为节点增加一个属性</strong></h3><p>通过节点的ID获取节点，Neo4j推荐通过where子句和ID函数来实现。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match (n)<br>where id(n)=11<br>set n.name = &#x27;华谊兄弟&#x27;<br>return n;<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/V14qX5UhGEZyFz7.png" alt="image-20220203115735318"></p><p><strong>为节点移除属性</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (n:农业) where id(n)=17816137 remove n.sortcode,n.targettable,n.unit,n.uuid<br></code></pre></td></tr></table></figure><h3 id="7-3-为节点增加标签"><a href="#7-3-为节点增加标签" class="headerlink" title="7.3 为节点增加标签"></a><strong>7.3 为节点增加标签</strong></h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match (n)<br>where id(n)=11<br>set n:公司<br>return n;<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/cuht9RON7U1d8mB.png" alt="image-20220203120010862"></p><h3 id="7-4-为关系增加属性"><a href="#7-4-为关系增加属性" class="headerlink" title="7.4 为关系增加属性"></a><strong>7.4 为关系增加属性</strong></h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs c">match (n)-[r]-&gt;(m)<br><span class="hljs-function">where <span class="hljs-title">id</span><span class="hljs-params">(n)</span></span>=<span class="hljs-number">10</span> <span class="hljs-function"><span class="hljs-keyword">and</span> <span class="hljs-title">id</span><span class="hljs-params">(m)</span></span>=<span class="hljs-number">11</span><br><span class="hljs-built_in">set</span> r.经纪人=<span class="hljs-string">&#x27;程晨&#x27;</span><br><span class="hljs-keyword">return</span> n;<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/TO7x9FKcABQWEMq.png" alt="image-20220203120501516"></p><p>此时图谱效果成</p><p>接着让刘德华也和华谊兄弟签约</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (a:Person),(c:公司)<br>WHERE a.name = &#x27;刘德华&#x27; AND c.name = &#x27;华谊兄弟&#x27;<br>CREATE (a)-[d:签约 &#123; 经纪人:&#x27;刘得得&#x27; &#125;]-&gt;(c)<br>RETURN d;<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/H8OlbStdpFkVM4B.png" alt="image-20220203120752503"></p><h3 id="7-5-MERGE"><a href="#7-5-MERGE" class="headerlink" title="7.5 MERGE"></a><strong>7.5 MERGE</strong></h3><p>Merge子句的作用有两个：当模式（Pattern）存在时，匹配该模式；当模式不存在时，创建新的模式，功能是match子句和create的组合。在merge子句之后，可以显式指定on creae和on match子句，用于修改绑定的节点或关系的属性。</p><p>通过merge子句，你可以指定图形中必须存在一个节点，该节点必须具有特定的标签，属性等，如果不存在，那么merge子句将创建相应的节点。</p><p><strong>通过merge子句匹配搜索模式</strong></p><p>匹配模式是：一个节点有Person标签，并且具有name属性；如果数据库不存在该模式，那么创建新的节点；如果存在该模式，那么绑定该节点；</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MERGE (m:Person &#123; name: &#x27;迈克尔·杰克逊&#x27; &#125;)<br>RETURN m;<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/Ybd4L1iyCqJ8TKe.png" alt="image-20220203121023519"></p><p><strong>在merge子句中指定on create子句</strong></p><p>如果需要创建节点，那么执行on create子句，修改节点的属性；<code>timestamp()</code>时间戳</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MERGE (m:Person &#123; name: &#x27;杰森·斯坦森&#x27; &#125;)<br>ON CREATE SET m.registertime = timestamp()<br>RETURN m.name, m.registertime<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/OVUcAfDN8H2MPhp.png" alt="image-20220203121212127"></p><p><strong>在merge子句中指定on match子句</strong></p><p>如果节点已经存在于数据库中，那么执行on match子句，修改节点的属性；节点属性不存在则新增</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MERGE (m:Person)<br>ON MATCH SET m.registertime = timestamp()<br>RETURN m.name, m.registertime<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/VGTwhEQtyAxbNe3.png" alt="image-20220203121519398"></p><p><strong>在merge子句中同时指定on create 和 on match子句(没有对应属性则不修改，不会新增属性)</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MERGE (m:Person&#123; name: &#x27;李连杰&#x27; &#125;)<br>ON CREATE SET m.registertime = timestamp()<br>ON MATCH SET m.offtime = timestamp()<br>RETURN m.name, m.registertime, m.offtime<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/ySrZTjXzonheHIq.png" alt="image-20220203121738648"></p><p><strong>merge子句用于match或create一个关系</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (m:Person &#123; name: &#x27;刘德华&#x27; &#125;),(n:Movie &#123; title: &#x27;神雕侠侣&#x27; &#125;)<br>MERGE (m)-[r:导演]-&gt;(n)<br>RETURN m.name, type(r), n.title<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/pxqduUJabfR87Ss.png" alt="image-20220203125002679"></p><p><strong>merge子句用于match或create多个关系</strong></p><p>赵薇既是神雕侠侣的导演,也是神雕侠侣的演员</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (m:Person &#123; name: &#x27;赵薇&#x27; &#125;),(n:Movie &#123; title: &#x27;神雕侠侣&#x27; &#125;)<br>MERGE (m)-[r:导演]-&gt;(n)&lt;-[r2:出演]-(m)<br>RETURN m.name, type(r),type(r2), n.title<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/rYKkoxzu7f3yPCQ.png" alt="image-20220203164701563"></p><p><strong>merge子句用于子查询</strong></p><p><strong>先添加基础数据</strong></p><p>创建城市节点</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs cypher">create (n:City &#123; name: &#x27;北京&#x27;,othername:&#x27;帝都&#x27;&#125;);<br>create (n:City &#123; name: &#x27;香港&#x27;,othername:&#x27;HongKong&#x27;&#125;);<br>create (n:City &#123; name: &#x27;台湾&#x27;,othername:&#x27;湾湾&#x27;&#125;);<br></code></pre></td></tr></table></figure><p>为Person标签的每个节点都增加一个属性 bornin</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match (n:Person)<br>set n.bornin = &#x27;&#x27;<br>return n;<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/9NRJYdGWz7FKMnU.png" alt="image-20220203164852127"></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match (n)<br>where id(n)=9<br>set n.bornin = &#x27;香港&#x27;<br>return n;<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/5qosTwCljSYymP4.png" alt="image-20220203165035186"></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match (n)<br>where n.name=&#x27;金城武&#x27;<br>set n.bornin = &#x27;台湾&#x27;<br>return n;<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/dNyL7sjHqWkhKIQ.png" alt="image-20220203165143523"></p><p><strong>需求:查找刘德华和金城武的信息和所在地的othername(相当于mysql 连表查询)</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (p:Person)<br>where p.name=&#x27;刘德华&#x27; or p.name=&#x27;金城武&#x27;<br>MERGE (c:City &#123; name: p.bornin &#125;)<br>RETURN p.name,p.born,p.bornin, c.othername;<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/OaZhRCxXv2yFSpj.png" alt="image-20220203165406817"></p><p>创建刘德华出生地是香港这条关系</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (a:Person),(c:City)<br>WHERE a.name = &#x27;刘德华&#x27; AND c.name = &#x27;香港&#x27;<br>CREATE (a)-[r:出生地]-&gt;(c)<br>RETURN r;<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/D5LYESXxaO3RuAp.png" alt="image-20220203165534007"></p><p>需求:给Person中每个节点都创建一个出生地的关系,没有则返回null</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (p:Person)<br>MERGE (c:City &#123; name: p.bornin &#125;)<br>MERGE (p)-[r:出生地]-&gt;(c)<br>RETURN p.name, p.bornin, c.othername;<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/5EDneQfwYPtbGXx.png" alt="image-20220203165645344"></p><p>删除这些关系</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match (a:Person)-[r:出生地]-&gt;(c:City&#123;name:&#x27;&#x27;&#125;) delete r<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/PqJgw1dVYvfQLcz.png" alt="image-20220203165816353"></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match (a:City)-[r:出生地]-&gt;(c:Person) delete r<br></code></pre></td></tr></table></figure><p>查询Person标签中不存在name属性的节点</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match (n:Person) where not exists(n.name) return n<br></code></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Match  (n:Person)  where not  exists(n.name)  delete  n<br></code></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs cypher">create (n:Prize &#123; name: &#x27;金马奖&#x27;&#125;);<br>create (n:Prize &#123; name: &#x27;奥斯卡金奖&#x27;&#125;);<br>create (n:Prize &#123; name: &#x27;金鸡奖&#x27;&#125;);<br>create (n:Prize &#123; name: &#x27;香港电影金像奖&#x27;&#125;);<br></code></pre></td></tr></table></figure><h3 id="7-6-跟实体相关的函数"><a href="#7-6-跟实体相关的函数" class="headerlink" title="7.6 跟实体相关的函数"></a><strong>7.6 跟实体相关的函数</strong></h3><p><strong>通过id函数，返回节点或关系的ID</strong></p><p><strong>查询Movie标签中和刘德华有关系的电影 id(节点和关系)</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (:Person &#123; name: &#x27;刘德华&#x27; &#125;)-[r]-&gt;(:Movie)<br>RETURN id(r);<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/wpAmrTDytjRO932.png" alt="image-20220203170433508"></p><p><strong>通过type函数，查询关系的类型</strong></p><p><strong>查询Person标签中和刘德华相关的关系(以下三种结果相同)</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (:Person &#123; name: &#x27;刘德华&#x27; &#125;)-[r]-&gt;()<br>RETURN type(r);<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/KOoVd5LIRAr1ue6.png" alt="image-20220203170658396"></p><p><strong>通过lables函数，查询节点的标签</strong></p><p><strong>查询和刘德华有关系的节点</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (:Person &#123; name: &#x27;刘德华&#x27; &#125;)-[r]-&gt;(p)<br>RETURN p;<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/nOPSRVkKYm2glMy.png" alt="image-20220203170851140"></p><p><strong>查询和刘德华有关系的标签(去重)</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (:Person &#123; name: &#x27;刘德华&#x27; &#125;)-[r]-&gt;(p)<br>RETURN distinct(labels(p))<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/FjBpdTghuELfNlM.png" alt="image-20220203171026549"></p><p><strong>通过keys函数，查看节点或关系的属性键</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (a)<br>WHERE a.name = &#x27;刘德华&#x27;<br>RETURN keys(a)<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/QuHUbdMYKvcoA31.png" alt="image-20220203171204245"></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (:Person &#123; name: &#x27;刘德华&#x27; &#125;)-[r]-&gt;(p) RETURN distinct(keys(r))<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/P17Ity2G6jcgpvl.png" alt="image-20220203171257645"></p><p><strong>通过properties()函数，查看节点或关系的属性</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (a)<br>WHERE a.name = &#x27;刘德华&#x27;<br>RETURN properties(a)<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/4ECLnrHsS1ybJNM.png" alt="image-20220203171441411"></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (:Person &#123; name: &#x27;刘德华&#x27; &#125;)-[r]-&gt;(p) RETURN properties(r)<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/02/03/pLR9nFN6YCd7bqw.png" alt="image-20220203171547474"></p><h2 id="8-跟索引相关的函数"><a href="#8-跟索引相关的函数" class="headerlink" title="8.跟索引相关的函数"></a><strong>8.跟索引相关的函数</strong></h2><h3 id="8-1-创建索引"><a href="#8-1-创建索引" class="headerlink" title="8.1 创建索引"></a><strong>8.1 创建索引</strong></h3><p><strong>创建单一属性索引</strong></p><p><strong>CREATE INDEX ON :Lable(property)</strong></p><p>Query:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">CREATE INDEX ON :Person(name)<br></code></pre></td></tr></table></figure><p>给数据库的:Person标签的name属性创建索引</p><p>Result:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Added 1 index, completed after 32 ms.<br></code></pre></td></tr></table></figure><p><strong>创建复合属性索引</strong></p><p><strong>CREATE INDEX ON :Label(prop1,…,propN)</strong></p><p>Query:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">CREATE INDEX ON :Person(age,country)<br></code></pre></td></tr></table></figure><p>Result:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">Added 1 index, completed after 4 ms.<br></code></pre></td></tr></table></figure><h3 id="8-2-查询索引"><a href="#8-2-查询索引" class="headerlink" title="8.2 查询索引"></a><strong>8.2 查询索引</strong></h3><p><strong>CALL db.Indexes</strong></p><h3 id="8-3-删除索引"><a href="#8-3-删除索引" class="headerlink" title="8.3 删除索引"></a><strong>8.3 删除索引</strong></h3><p><strong>DROP INDEX ON :LABEL(property）</strong></p><p>Query:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">DROP INDEX ON :Person(firstname)<br></code></pre></td></tr></table></figure><p><strong>DROP INDEX ON :LABEL(prop1,…,propN)</strong></p><p>Query:</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">DROP INDEX ON :Person(age,country)<br></code></pre></td></tr></table></figure><h3 id="8-4-备份与导入"><a href="#8-4-备份与导入" class="headerlink" title="8.4 备份与导入"></a>8.4 备份与导入</h3><p>备份/导出</p><p>要以管理员身份运行</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">neo4j-admin dump --database=graph.db --to=E:\neo4jdata<br></code></pre></td></tr></table></figure><p>导入</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">neo4j-admin load --from=E:\neo4jdata\graph.db.dump --database=graph.db --force<br></code></pre></td></tr></table></figure><p>导入csv</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs shell">USING PERIODIC COMMIT 500 LOAD CSV FROM &quot;file:///D:\\test.csv&quot; AS line  MERGE (:`顶顶顶` &#123;name:line[0]&#125;)<br>LOAD CSV WITH HEADERS FROM &quot;file:///C:\\Program Files\\Java\\neo4j-community-3.4.7\\import\\stock_concept.csv&quot;<br>AS line<br>return line.n<br></code></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs cypher">USING PERIODIC COMMIT 10  <br>LOAD CSV FROM &quot;file:///node.csv&quot; AS line  <br>create (a:Node&#123;name:line[0]&#125;)  <br></code></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs cypher">USING PERIODIC COMMIT<br>LOAD CSV FROM &#x27;file:///concept.csv&#x27; AS row<br>CREATE (n:概念&#123;name:row[1],uuid:row[0]&#125;)<br></code></pre></td></tr></table></figure><p>csv 不带header方式</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs cypher">USING PERIODIC COMMIT<br>LOAD CSV  FROM &quot;file:///executive_stock.csv&quot; AS row<br>MATCH (n:高管 &#123;uuid: row[0]&#125;)<br>MATCH (m:企业 &#123;uuid: row[1]&#125;)<br>MERGE (n)-[:RE&#123;name:row[2]&#125;]-&gt;(m) <br></code></pre></td></tr></table></figure><p>带header方式</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs cypher">USING PERIODIC COMMIT<br>LOAD CSV WITH HEADERS FROM &#x27;file:///industry.csv&#x27; AS row<br>CREATE (:行业&#123;name:row.name,uuid:row.uuid&#125;)<br></code></pre></td></tr></table></figure><p><strong>apoc 导入</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">call apoc.import.csv([&#123;fileName: &#x27;D:\\text\\ctwh\\ctwh.csv&#x27;, labels: [&#x27;ctwh&#x27;]&#125;], [], &#123;&#125;)<br></code></pre></td></tr></table></figure><p><strong>apoc导出</strong></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (n:`zhctwh`)-[r:RE]-&gt;(m:`zhctwh`)<br>WITH collect(DISTINCT n) AS cn, collect(DISTINCT m) AS cm, collect(r) AS rships<br>CALL apoc.export.csv.data(cn+cm, rships, &quot;ctwh-re.csv&quot;, &#123;&#125;)<br>YIELD file, source, format, nodes, relationships, properties, time, rows, batchSize, batches, done, data<br>RETURN file, source, format, nodes, relationships, properties, time, rows, batchSize, batches, done, data<br></code></pre></td></tr></table></figure><p>注意：导出文件如果如上面语句没写路径，默认在安装目录的根目录下，bin所在的同级目录</p><h2 id="关于neo4j查询多深度关系节点"><a href="#关于neo4j查询多深度关系节点" class="headerlink" title="关于neo4j查询多深度关系节点"></a><strong>关于neo4j查询多深度关系节点</strong></h2><h3 id="1-使用with关键字"><a href="#1-使用with关键字" class="headerlink" title="1.使用with关键字"></a><strong>1.使用with关键字</strong></h3><p>查询三层级关系节点如下：with可以将前面查询结果作为后面查询条件</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match (na:company)-[re]-&gt;(nb:company) where na.id = &#x27;11&#x27; WITH na,re,nb match (nb:company)-[re2]-&gt;(nc:company) return na,re,nb,re2,nc<br></code></pre></td></tr></table></figure><h3 id="2-直接拼接关系节点查询"><a href="#2-直接拼接关系节点查询" class="headerlink" title="2.直接拼接关系节点查询"></a><strong>2.直接拼接关系节点查询</strong></h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match (na:company&#123;id:&#x27;12399145&#x27;&#125;)-[re]-&gt;(nb:company)-[re2]-&gt;(nc:company) return na,re,nb,re2,nc<br></code></pre></td></tr></table></figure><h3 id="3-为了方便，可以将查询结果赋给变量，然后返回"><a href="#3-为了方便，可以将查询结果赋给变量，然后返回" class="headerlink" title="3.为了方便，可以将查询结果赋给变量，然后返回"></a><strong>3.为了方便，可以将查询结果赋给变量，然后返回</strong></h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match data=(na:company&#123;id:&#x27;12&#x27;&#125;)-[re]-&gt;(nb:company)-[re2]-&gt;(nc:company) return data<br></code></pre></td></tr></table></figure><h3 id="4-使用深度运算符"><a href="#4-使用深度运算符" class="headerlink" title="4.使用深度运算符"></a><strong>4.使用深度运算符</strong></h3><p>当实现多深度关系节点查询时，显然使用以上方式比较繁琐。</p><p>可变数量的关系-&gt;节点可以使用**-[:TYPE*minHops..maxHops]-&gt;**。</p><p>查询：</p><p>如果在1到3的关系中存在路径，将返回开始点和结束点。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match data=(na:company&#123;id:&#x27;12399145&#x27;&#125;)-[*1..3]-&gt;(nb:company) return data<br></code></pre></td></tr></table></figure><h2 id="其他"><a href="#其他" class="headerlink" title="其他"></a>其他</h2><h3 id="使用APOC库"><a href="#使用APOC库" class="headerlink" title="使用APOC库"></a><strong>使用APOC库</strong></h3><p><a href="https://neo4j-contrib.github.io/neo4j-apoc-procedures/">https://neo4j-contrib.github.io/neo4j-apoc-procedures/</a></p><h3 id="合并重复节点"><a href="#合并重复节点" class="headerlink" title="合并重复节点"></a><strong>合并重复节点</strong></h3><p>先装apoc  过程如下</p><p><a href="https://blog.csdn.net/graphway/article/details/78957415">https://blog.csdn.net/graphway/article/details/78957415</a></p><p>安装完成 执行  <code>return apoc.version() </code> 查看下版本</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (n:国家电网)<br>WITH n.name AS name, COLLECT(n) AS nodelist, COUNT(*) AS count<br>WHERE count &gt; 1<br>CALL apoc.refactor.mergeNodes(nodelist) YIELD node<br>RETURN node<br></code></pre></td></tr></table></figure><p>查询某个节点有关系的3级及以内的路径</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs cypher">MATCH (n:`贵州`) WHERE n.name=&#x27;交通事件&#x27;<br>CALL apoc.path.spanningTree(n, &#123;maxLevel:3&#125;) YIELD path<br>RETURN path;<br></code></pre></td></tr></table></figure><h3 id="复制领域"><a href="#复制领域" class="headerlink" title="复制领域"></a><strong>复制领域</strong></h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match(n:菊花) MERGE (:大萨达&#123;name:n.name&#125;)<br>match(n:菊花)-[r]-&gt;(q:菊花)<br>with n, r, q<br>match (o:大萨达&#123;name:n.name&#125;), (m:大萨达&#123;name:q.name&#125;)<br>MERGE (o)-[:RE&#123;name:r.name&#125;]-&gt;(m)<br></code></pre></td></tr></table></figure><h3 id="keys函数"><a href="#keys函数" class="headerlink" title="keys函数"></a><strong>keys函数</strong></h3><p>查询某个属性大于0 的节点</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match(n) where any(x in keys(n) where n[x] &gt; 0) return n<br></code></pre></td></tr></table></figure><p>查询所有属性大于0的节点</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match(n) where all(x.uuid in keys(n) where n[x.uuid] &gt; 0) return n   <br></code></pre></td></tr></table></figure><p>x在any中是一个变量，并不是属性</p><p>uuid大于0</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match(n) where any(uuid in keys(n) where n[uuid] &gt; 0) return n <br></code></pre></td></tr></table></figure><p>所有uuid都大于0</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match(n) where all(uuid in keys(n) where n[uuid] &gt; 0) return n<br></code></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match(n) where any(querytype in keys(n) where n[querytype] = 0) return n<br></code></pre></td></tr></table></figure><h3 id="修改密码"><a href="#修改密码" class="headerlink" title="修改密码"></a><strong>修改密码</strong></h3><p>进入neo4j提供的可视化界面broswer</p><p>输入： :server change-password</p><p>键入原密码及新密码，即可修改</p><h3 id="设置权重"><a href="#设置权重" class="headerlink" title="设置权重"></a><strong>设置权重</strong></h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match (n:`测试权重`&#123;name:&#x27;项目名称&#x27;&#125;),(m:`测试权重`&#123;name:&#x27;设计速度&#x27;&#125;)<br>MATCH p=(n)-[*]-(m)<br>with p,reduce(s=0,r in rels(p)|s+toInt(r.name)) as dist<br>return p,dist order by dist asc<br></code></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match (n:`交通规划设计`&#123;name:&#x27;项目名称&#x27;&#125;),(m:`交通规划设计`&#123;name:&#x27;设计速度&#x27;&#125;)<br>CALL apoc.algo.dijkstra(n,m,&#x27;RE&#x27;,&#x27;weight&#x27;)yield path as path,weight as weight<br>return path,weight<br></code></pre></td></tr></table></figure><h3 id="最短路径"><a href="#最短路径" class="headerlink" title="最短路径"></a><strong>最短路径</strong></h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match (n:`测试权重`&#123;name:&#x27;项目名称&#x27;&#125;),(m:`测试权重`&#123;name:&#x27;设计速度&#x27;&#125;),<br>p=shortestpath((n)-[*..10]-(m))<br>RETURN p<br></code></pre></td></tr></table></figure><h3 id="所有路径"><a href="#所有路径" class="headerlink" title="所有路径"></a><strong>所有路径</strong></h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match (n:`测试权重`&#123;name:&#x27;项目名称&#x27;&#125;),(m:`测试权重`&#123;name:&#x27;设计速度&#x27;&#125;),<br><br>p=allshortestpaths((n)-[*..10]-(m))<br><br>RETURN p<br></code></pre></td></tr></table></figure><h3 id="多个节点两两间互相求最短路径"><a href="#多个节点两两间互相求最短路径" class="headerlink" title="多个节点两两间互相求最短路径"></a><strong>多个节点两两间互相求最短路径</strong></h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs cypher">with [&#x27;项目名称&#x27;,&#x27;工可批复单位&#x27;,&#x27;设计速度&#x27;] as indicator_list<br>match (n:`交通规划设计`) where n.name in indicator_list<br>with collect(n) as nodes<br>unwind nodes as source<br>unwind nodes as target<br>with source,target where id(source)<br>match paths = shortestPath((source)-[*0..2]-(target)) <br>with paths limit 20000<br>return paths<br></code></pre></td></tr></table></figure><p>带条件的</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs cypher">with [3105, 200025928, 200025929, 151286502, 135660351] as id_list<br>match (v:vertices) where v.id in id_list<br>  with collect(v) as nodes<br>  unwind nodes as source<br>  unwind nodes as target<br>  with source,target where id(source)<br>match paths = shortestPath((source)-[:HOLDER|MANAGER*0..2]-(target)) where all(x in nodes(paths) where x.id&lt;&gt;3105)<br>  with paths limit 20000<br>  return paths<br></code></pre></td></tr></table></figure><h3 id="多标签查询"><a href="#多标签查询" class="headerlink" title="多标签查询"></a>多标签查询</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs cypher">match (n) where any(label in labels(n) WHERE label in [&#x27;A 标签&#x27;, &#x27;B 标签&#x27;]) return n<br></code></pre></td></tr></table></figure><h3 id="查询字段类型"><a href="#查询字段类型" class="headerlink" title="查询字段类型"></a>查询字段类型</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs cypher">apoc.meta.type<br>String cypher = &quot;match(n:`zhctwh`) where  apoc.meta.type(n.similar)=&#x27;STRING&#x27; return n&quot;;<br></code></pre></td></tr></table></figure>]]></content>
    
    
    <categories>
      
      <category>知识图谱</category>
      
    </categories>
    
    
    <tags>
      
      <tag>neo4j</tag>
      
      <tag>cypher</tag>
      
      <tag>知识图谱</tag>
      
    </tags>
    
  </entry>
  
  
  
  <entry>
    <title>解决语雀导出markdown文件图片不显示问题</title>
    <link href="/2022/01/29/%E7%AC%94%E8%AE%B0/%E8%A7%A3%E5%86%B3%E8%AF%AD%E9%9B%80%E5%AF%BC%E5%87%BAmarkdown%E6%96%87%E4%BB%B6%E5%9B%BE%E7%89%87%E4%B8%8D%E6%98%BE%E7%A4%BA%E9%97%AE%E9%A2%98/"/>
    <url>/2022/01/29/%E7%AC%94%E8%AE%B0/%E8%A7%A3%E5%86%B3%E8%AF%AD%E9%9B%80%E5%AF%BC%E5%87%BAmarkdown%E6%96%87%E4%BB%B6%E5%9B%BE%E7%89%87%E4%B8%8D%E6%98%BE%E7%A4%BA%E9%97%AE%E9%A2%98/</url>
    
    <content type="html"><![CDATA[<h1 id="解决语雀导出markdown文件图片不显示问题"><a href="#解决语雀导出markdown文件图片不显示问题" class="headerlink" title="解决语雀导出markdown文件图片不显示问题"></a>解决语雀导出markdown文件图片不显示问题</h1><h2 id="问题"><a href="#问题" class="headerlink" title="问题"></a>问题</h2><p>使用语雀记笔记发现导出markdown文件后，图片无法正常显示</p><p><img src="https://s2.loli.net/2022/01/29/6JEv4bna1Z7dOty.png" alt="image-20220129102813109"></p><h2 id="解决办法"><a href="#解决办法" class="headerlink" title="解决办法"></a>解决办法</h2><p>语雀转成md文件导出，图片无法正常显示。把url地址中png后面的部分，即#clientId开始全部删掉即可。</p><span id="more"></span><h2 id="脚本解决"><a href="#脚本解决" class="headerlink" title="脚本解决"></a>脚本解决</h2><p>但是一个一个删除还是太麻烦，所以还是写python脚本来完成这项工作，代码如下：</p><p>注意没有使用绝对路径，所以使用时将该脚本与文件放在同一目录下</p><figure class="highlight python"><table><tr><td class="gutter"><div class="code-wrapper"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></div></td><td class="code"><pre><code class="hljs python"><span class="hljs-comment"># -*- encoding: utf-8 -*-</span><br><span class="hljs-keyword">import</span> re<br><br>new_md = []<br><br><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">title</span>():</span><br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&#x27;+------------------------------------------&#x27;</span>)<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&#x27;[+]  功  能: 语雀文档导出md文件后图片修复 &#x27;</span>)<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&#x27;[+]  注  意: 将该脚本与文件放在同一目录下 &#x27;</span>)<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&#x27;+------------------------------------------&#x27;</span>)<br><br><br><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">deal_yuque</span>(<span class="hljs-params">new_md, old_path</span>):</span><br>    <span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(old_path, <span class="hljs-string">&#x27;r&#x27;</span>, encoding=<span class="hljs-string">&#x27;utf-8&#x27;</span>, errors=<span class="hljs-string">&#x27;ignore&#x27;</span>) <span class="hljs-keyword">as</span> f:<br>        <span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> f.readlines():<br>            line = re.sub(<span class="hljs-string">r&#x27;png#(.*)+&#x27;</span>, <span class="hljs-string">&#x27;png)&#x27;</span>, line)<br>            <span class="hljs-comment"># print(line)</span><br>            new_md.append(line)<br><br>    <span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(old_path, <span class="hljs-string">&#x27;w&#x27;</span>, encoding=<span class="hljs-string">&#x27;utf-8&#x27;</span>, errors=<span class="hljs-string">&#x27;ignore&#x27;</span>) <span class="hljs-keyword">as</span> f:<br>        <span class="hljs-keyword">for</span> new_md <span class="hljs-keyword">in</span> new_md:<br>            f.write(<span class="hljs-built_in">str</span>(new_md))<br><br><br><span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">&#x27;__main__&#x27;</span>:<br>    title()<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&#x27;[+]  请输入您的文件名称, 如：文件名称.md&#x27;</span>)<br>    old_path = <span class="hljs-built_in">input</span>(<span class="hljs-string">&#x27;[+]  文件名称：&#x27;</span>)<br>    <span class="hljs-comment"># new_path = &#x27;new_&#x27; + old_path</span><br>    deal_yuque(new_md, old_path)<br>    <span class="hljs-built_in">print</span>(<span class="hljs-string">&#x27;[+]  \033[36m修复完成 &#x27;</span>)<br></code></pre></td></tr></table></figure><h2 id="生成exe可执行文件"><a href="#生成exe可执行文件" class="headerlink" title="生成exe可执行文件"></a>生成exe可执行文件</h2><h3 id="1-pyinstaller-介绍"><a href="#1-pyinstaller-介绍" class="headerlink" title="1. pyinstaller 介绍"></a>1. pyinstaller 介绍</h3><p>pyinstaller将Python脚本打包成可执行程序，使在没有Python环境的机器上运行</p><h3 id="2-pyinstaller在windows下的安装"><a href="#2-pyinstaller在windows下的安装" class="headerlink" title="2. pyinstaller在windows下的安装"></a>2. pyinstaller在windows下的安装</h3><p>使用命令pip install pyinstaller即可</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">pip install pyinstaller<br></code></pre></td></tr></table></figure><p>出现Successfully installed pyinstaller-3.1.1 pypiwin32-219即表示安装成功</p><h3 id="3-打包"><a href="#3-打包" class="headerlink" title="3. 打包"></a>3. 打包</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">pyinstaller --onefile --nowindowed 要打包的文件.py<br></code></pre></td></tr></table></figure><p>就会在当前文件下形成build文件夹、dist文件夹和.spec文件。<br>dist里就是guess_exe.exe可执行文件。</p><blockquote><p>附基本语法</p></blockquote><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs shell">pyinstaller options myscript.py<br>常用的可选参数如下：<br>--onefile 将结果打包成一个可执行文件<br>--onedir 将所有结果打包到一个文件夹中，该文件夹包括一个可执行文件和可执行文件执行时需要的依赖文件（默认）<br>--paths=DIR 设置导入路径<br>--distpath=DIR 设置将打包的结果文件放置的路径<br>--specpath=DIR 设置将spec文件放置的路径<br>--windowed 使用windows子系统执行，不会打开命令行（只对windows有效）<br>--nowindowed 使用控制台子系统执行（默认）（只对windows有效）<br>--icon=&lt;FILE.ICO&gt; 将file.ico添加为可执行文件的资源(只对windows有效）<br></code></pre></td></tr></table></figure><h2 id="愉快使用"><a href="#愉快使用" class="headerlink" title="愉快使用"></a>愉快使用</h2><p>将生成的exe文件放到笔记文件夹同目录，双击即可使用</p><p><img src="https://s2.loli.net/2022/01/29/ND4rpefxtGQPUSH.png" alt="image-20220129103839267"></p>]]></content>
    
    
    <categories>
      
      <category>技术分享</category>
      
    </categories>
    
    
    <tags>
      
      <tag>技术分享</tag>
      
      <tag>工具</tag>
      
    </tags>
    
  </entry>
  
  
  
  <entry>
    <title>各种学习网站汇总</title>
    <link href="/2022/01/28/%E7%AC%94%E8%AE%B0/%E5%90%84%E7%A7%8D%E5%AD%A6%E4%B9%A0%E7%BD%91%E5%9D%80%E6%B1%87%E6%80%BB/"/>
    <url>/2022/01/28/%E7%AC%94%E8%AE%B0/%E5%90%84%E7%A7%8D%E5%AD%A6%E4%B9%A0%E7%BD%91%E5%9D%80%E6%B1%87%E6%80%BB/</url>
    
    <content type="html"><![CDATA[<h1 id="非常有用的网站（各种学习网站）"><a href="#非常有用的网站（各种学习网站）" class="headerlink" title="非常有用的网站（各种学习网站）"></a>非常有用的网站（各种学习网站）</h1><h2 id="几个神仙小众网站"><a href="#几个神仙小众网站" class="headerlink" title="几个神仙小众网站"></a>几个神仙小众网站</h2><p>人人自学网 最全的免费教程网站<a href="http://www.rrzxw.net/">http://www.rrzxw.net/</a></p><p>正版中国 正版软件限时免费<a href="https://getitfree.cn/">https://getitfree.cn/</a> </p><p>Mikutap解压娱乐二次元网站 <a href="https://aidn.jp/mikutap/">https://aidn.jp/mikutap/</a> </p><p>arkie根据文字内容自动生成海报<a href="https://www.arkie.cn/welcome">https://www.arkie.cn/welcome</a> </p><span id="more"></span><p>PPT模板<a href="http://www.hippter.com/">http://www.hippter.com/</a> </p><p>吾道幻灯片 PPT模板<a href="https://www.99ppt.com/S.html">https://www.99ppt.com/S.html</a></p><p>各种diy <a href="https://www.ehow.com/">https://www.ehow.com/</a> </p><p>鸠摩搜索 电子书搜索下载网站<a href="https://www.jiumodiary.com/">https://www.jiumodiary.com/</a> </p><p>电子书下载网站<a href="https://www.jiumodiary.com/">https://www.jiumodiary.com/</a> </p><p>大学生资源网<a href="http://www.dxzy163.com/">http://www.dxzy163.com/</a></p><p>word联盟<a href="http://wordlm.com/">http://wordlm.com/</a></p><p>视频编辑学习<a href="https://www.doyoudo.com/">https://www.doyoudo.com/</a></p><p>百度文库下载 <a href="file:///C:\Users\13740\Downloads\yaersen.com">yaersen.com</a></p><p>考试酷 <a href="https://examcoo.com/">https://examcoo.com/</a></p><p>在线好工具 nicetool.net 好像不能访问了</p><p>渣男说话的艺术<a href="https://lovelive.tools/">https://lovelive.tools/</a></p><p>logo图库<a href="https://www.60logo.com/list">https://www.60logo.com/list</a></p><p>音乐<a href="https://icons8.com/music">https://icons8.com/music</a></p><p>天空之城摄影<a href="https://www.skypixel.com/">https://www.skypixel.com/</a></p><p>抠图<a href="https://www.remove.bg/zh">https://www.remove.bg/zh</a></p><p>声音生成字幕等<a href="https://jianwai.youdao.com/">https://jianwai.youdao.com/</a></p><p>免费在线格式转换工具<a href="http://www.alltoall.net/">http://www.alltoall.net/</a></p><p>平面设计图片设计做图达人<a href="https://www.canva.cn/">https://www.canva.cn/</a></p><p>智能转写翻译服务<a href="http://sight.youdao.com/">http://sight.youdao.com/</a></p><p>巧匠课堂一个可以学设计的网站 <a href="https://www.2qj.com/">https://www.2qj.com/</a></p><p>小语种论坛 声同 <a href="http://www.somdom.com/">http://www.somdom.com/</a></p><h2 id="学习资源网站"><a href="#学习资源网站" class="headerlink" title="学习资源网站"></a>学习资源网站</h2><ol><li><p>小木虫（ <a href="http://emuch.net/">http://emuch.net/</a> ）里边有不少学术科研用得到的资料，且全部为免费的</p></li><li><p>普特英语 <a href="http://putclub.com/">http://putclub.com/</a> 增强英语听说的一个绝好地方</p></li><li><p>国家自然科学基金（ <a href="http://www.nsfc.gov.cn/Portal0/default40.htm">http://www.nsfc.gov.cn/Portal0/default40.htm</a> ）堪称中国科学研究的风向标</p></li><li><p>华军软件园（ <a href="http://www.newhua.com/index.htm">http://www.newhua.com/index.htm</a> ）下载的软件基本能用。</p></li><li><p>博研联盟（ <a href="http://www.bylm.net/forum/index.php">http://www.bylm.net/forum/index.php</a> ） -</p></li><li><p>人大经济论坛（ <a href="http://www.pinggu.org/bbs">http://www.pinggu.org/bbs</a> ）经济学资源下载、学习交流的网站。</p></li><li><p>丁香园（ <a href="http://www.dxy.cn/portal">http://www.dxy.cn/portal</a> ）医学、药学、生命科学专业论坛</p></li><li><p>中国生命科学论坛（ <a href="http://bbs.bioon.com/">http://bbs.bioon.com/</a> ）推荐理由：医学、药学、生命科学专业论坛。</p></li></ol><p>9.<a href="http://www.bbc.co.uk/worldservice/">http://www.bbc.co.uk/worldservice/</a> （学听力，学地道英语）</p><ol start="10"><li><p>教育学习资源搜索门户 – 搜教网 <a href="http://www.soojoo.cn/">http://www.soojoo.cn</a> 考研，英语， it 学习资源一网打尽</p></li><li><p>仲一互助游网 <a href="http://www.jooinn.com/">http://www.jooinn.com/</a> 没钱也能周游中国 !</p></li><li><p>开复学生网 <a href="http://kaifulee.com/google">http://kaifulee.com/google</a> 中国总裁为中国学生做的</p></li><li><p>我要模考网词汇练习： <a href="http://www.51mokao.com/Users/Use">http://www.51mokao.com/Users/Use</a> … &amp;type=languages</p></li><li><p>学习英语的好帮手。 <a href="http://edu.taisha.org/">http://edu.taisha.org</a></p></li><li><p>词汇量相当的惊人，有单词本，里边还有好多学习课程。 <a href="http://www.dict.cn/">http://www.dict.cn</a></p></li><li><p>设计之家，平面设计爱好者。 <a href="http://www.sj33.cn/">http://www.sj33.cn</a></p></li><li><p>专门的图标制作论坛。 <a href="http://www.iconfans.com/">http://www.iconfans.com</a></p></li><li><p>免费提供桌面壁纸。 <a href="http://www.kkdesk.com/">http://www.kkdesk.com</a></p></li><li><p>3 连素材，资源不少，免费。 <a href="http://www.3lian.com/">http://www.3lian.com</a></p></li><li><p>这是一个比较专业的设计类网站，在这里可以领略众多意想不到的创 </p></li></ol><p> <a href="http://www.visionunion.com/">http://www.visionunion.com</a></p><ol start="21"><li>各种考证网站汇总： <a href="http://www.topsage.com/">http://www.topsage.com/</a></li></ol><h2 id="考试资源网站"><a href="#考试资源网站" class="headerlink" title="考试资源网站"></a>考试资源网站</h2><ol start="22"><li>考试 163 ： <a href="http://www.test163.com/">http://www.test163.com</a> ( 大量的资格认真考试试题，计算机，英语视听材料 )</li></ol><p>23.IT 认证考试资源网 [<a href="http://www.itexamprep.com/">http://www.itexamprep.com</a>( 大量 IT 认证考试题库 )</p><ol start="24"><li><p>中国大学生网 [<a href="http://www.chinadaxuesheng.com/">http://www.chinadaxuesheng.com</a>( 题库 , 模拟题 , 论文 , 小学大学 )</p></li><li><p>中国考试网网 [<a href="http://www.sinoexam.com.cn/">http://www.sinoexam.com.cn</a>( 太多了 )</p></li><li><p>中国考研网 [<a href="http://www/">http://www</a>. 好好学习，天天校内 an.com( 想考研究生来看看吧 , 大量免费资源 )</p></li><li><p>考研网 [<a href="http://www.kaoyan.net/">http://www.kaoyan.net</a>( 也是考研的网站 , 大量免费资源 )</p></li><li><p>中国自考网 [<a href="http://www.chinazikao.com/">http://www.chinazikao.com</a>( 自学考试相关资源 )</p></li><li><p>出国考试网 [<a href="http://www.007test.com/">http://www.007test.com</a>( 出国考试过关习题等 )</p></li><li><p>天下资源网 [<a href="http://www.da126.com/">http://www.da126.com</a>( 出国考试过关习题 , 英语视听材料等 ) &lt; 外语学习 &gt;</p></li><li><p>择校学习网 [<a href="http://www.zexiao.com/">http://www.zexiao.com</a>( 出国学习外语 , 咨询等 )</p></li><li><p>163 考试网 [<a href="http://www.test163.com/">http://www.test163.com</a>( 要过 CET 的朋友要去看看，还有听力资料啊 )</p></li><li><p>英语之声 [<a href="http://www.4english.cn/">http://www.4english.cn</a>( 网上学习英语的好地方 )</p></li><li><p>疯狂英语俱乐部 [/]<a href="http://www.crazyenglish.org/">http://www.crazyenglish.org</a> 想了解疯狂英语吗 ?)</p></li><li><p>在线英语杂志 [<a href="http://www.englishcn.com/">http://www.englishcn.com</a>( 不错的地方 )</p></li><li><p>英语写作网 [<a href="http://www.4ewriting.com/">http://www.4ewriting.com</a>( 英语协作技巧等 )</p></li><li><p>英语周报 [<a href="http://www.ew.com.cn/">http://www.ew.com.cn</a>( 学习英语的好地方 )</p></li><li><p>英语角 [<a href="http://www.english-corner.com.cn/">http://www.english-corner.com.cn</a>( 看看吧 )</p></li><li><p>英语学习 <a href="http://www.dd234.com/">www.dd234.com</a></p></li></ol><h2 id="免费学习全世界最好的在线课程"><a href="#免费学习全世界最好的在线课程" class="headerlink" title="免费学习全世界最好的在线课程"></a>免费学习全世界最好的在线课程</h2><p>一流的大学的课程  <a href="https://www.coursera.org/">https://www.coursera.org/</a></p><p>果壳旗下的MOOC学院 <a href="http://mooc.guokr.com/">http://mooc.guokr.com/</a> </p><p>中国大学精品开放课程 爱课程  <a href="http://www.icourses.cn/home/">http://www.icourses.cn/home/</a> </p><p>网易公开课  <a href="http://open.163.com/">http://open.163.com/</a> </p><p>微软虚拟学院  <a href="http://www.microsoftvirtualacademy.com/">http://www.microsoftvirtualacademy.com/</a> </p><p>极客学院  <a href="http://www.jikexueyuan.com/">http://www.jikexueyuan.com/</a> </p><p>麦子学院 <a href="http://www.maiziedu.com/">http://www.maiziedu.com/</a> </p><p>番薯学院  <a href="http://www.fanshuxueyuan.com/">http://www.fanshuxueyuan.com/</a> </p><p>慕课网  <a href="http://www.imooc.com/">http://www.imooc.com/</a> </p><p>我要自学网  <a href="http://www.51zxw.net/default.aspx">http://www.51zxw.net/default.aspx</a> </p><p>百度传课   <a href="http://www.chuanke.com/">http://www.chuanke.com/</a> </p><p>腾讯精品课程   <a href="http://class.qq.com/">http://class.qq.com/</a></p><p>好大学在线  <a href="http://www.cnmooc.org/">http://www.cnmooc.org/</a></p><p>华文慕课  <a href="http://www.chinesemooc.org/">http://www.chinesemooc.org/</a></p><h2 id="下面这几个是纯英文的"><a href="#下面这几个是纯英文的" class="headerlink" title="下面这几个是纯英文的"></a>下面这几个是纯英文的</h2><p>E dX   <a href="https://www.edx.org/">https://www.edx.org/</a></p><p>Udacity  <a href="https://www.udacity.com/">https://www.udacity.com/</a></p><p>Open Learn  <a href="http://www.open.edu/openlearn/">http://www.open.edu/openlearn/</a></p><p>Iversity  <a href="https://iversity.org/">https://iversity.org/</a></p><p>Open2 study  <a href="https://www.open2study.com/">https://www.open2study.com/</a> </p><h2 id="学习计算机类的网站"><a href="#学习计算机类的网站" class="headerlink" title="学习计算机类的网站"></a>学习计算机类的网站</h2><p>优才学院   <a href="http://www.ucai.cn/">http://www.ucai.cn/</a></p><p>计蒜课   <a href="http://www.jisuanke.com/">http://www.jisuanke.com/</a></p><p>CODE  <a href="http://code.csdn.net/">http://code.csdn.net/</a></p><p>开课吧   <a href="http://www.kaikeba.com/">http://www.kaikeba.com/</a></p><h2 id="三大-BAT-巨头-在线教育"><a href="#三大-BAT-巨头-在线教育" class="headerlink" title="三大 BAT 巨头 在线教育"></a>三大 BAT 巨头 在线教育</h2><p>百度 ：</p><p>百度传课   <a href="http://www.chuanke.com/">http://www.chuanke.com/</a> </p><p>百度营销大学   <a href="http://edu.baidu.com/elearning.html">http://edu.baidu.com/elearning.html</a> </p><p>百度前端技术学院  <a href="http://ife.baidu.com/">http://ife.baidu.com/</a> </p><p>百度深度学习 实验室   <a href="http://idl.baidu.com/index.html">http://idl.baidu.com/index.html</a> </p><p>百度预测   <a href="http://trends.baidu.com/">http://trends.baidu.com/</a> </p><p>腾讯 :</p><p>腾讯大学 :     <a href="http://daxue.qq.com/">http://daxue.qq.com/</a></p><p>微信学院   <a href="http://daxue.qq.com/wechat">http://daxue.qq.com/wechat</a></p><p>开放平台学院   <a href="http://daxue.qq.com/open">http://daxue.qq.com/open</a></p><p>互联网学院   <a href="http://daxue.qq.com/internet">http://daxue.qq.com/internet</a></p><p>营销学院   <a href="http://daxue.qq.com/mkt">http://daxue.qq.com/mkt</a> </p><p>阿里</p><p>淘宝大学  <a href="http://daxue.taobao.com/">http://daxue.taobao.com/</a> </p><p>1688商学院 <a href="http://peixun.1688.com/">http://peixun.1688.com/</a> </p><p>阿里研究院   <a href="http://www.aliresearch.com/">http://www.aliresearch.com/</a> </p><p>免费学韩语的网站 :<a href="http://www.koreaxin.com/">www.koreaxin.com</a></p><p>各种考证网站汇总： <a href="http://www.topsage.com/">http://www.topsage.com/</a></p><p>中国 IT 实验室： <a href="http://www.chinaitlab.com/">http://www.chinaitlab.com/</a></p><h2 id="ENGLISH-PART"><a href="#ENGLISH-PART" class="headerlink" title="ENGLISH PART"></a>ENGLISH PART</h2><p>英语四级考试网  <a href="http://www.cet4v.com/">http://www.cet4v.com/</a></p><p>英语六级考试网  <a href="http://www.cet6w.com/">http://www.cet6w.com/</a></p><p>四六级考试网  <a href="http://www.cet-46.com/default.asp">http://www.cet-46.com/default.asp</a></p><p>中国雅思网  <a href="http://www.cnielts.com/">http://www.cnielts.com/</a></p><p>无忧雅思网  <a href="http://www.51ielts.com/">http://www.51ielts.com/</a></p><p>3G 雅思网 <a href="http://www.3gbbs.com/">http://www.3gbbs.com/</a></p><p>中国考试网  <a href="http://www.sinoexam.com.cn/">http://www.sinoexam.com.cn/</a></p><p>E 学网 <a href="http://www.exue.com/">http://www.exue.com/</a></p><p>旺旺英语  <a href="http://www.wwenglish.com/">http://www.wwenglish.com/</a></p><p>普特英语听力  <a href="http://www.putclub.com/">http://www.putclub.com/</a></p><p>中国英语学习网  <a href="http://www.24en.com/">http://www.24en.com/</a></p><p>英语翻译吧  <a href="http://www.fanyi8.com/">http://www.fanyi8.com/</a></p><p>英文写作网  <a href="http://www.4ewriting.com/">http://www.4ewriting.com/</a></p><p>新东方网络课堂  <a href="http://www.tol24.com/">http://www.tol24.com/</a></p><p>英语周报  <a href="http://www.ew.com.cn/">http://www.ew.com.cn/</a></p><p>英语 365 <a href="http://e365.cc163.net/">http://e365.cc163.net/</a></p><p>英文早报  <a href="http://gzmp.dayoo.com/">http://gzmp.dayoo.com/</a></p><p>英语时空  <a href="http://www.yysk.net/">http://www.yysk.net/</a></p><p>中国英语学习网  <a href="http://www.24en.com/">http://www.24en.com/</a></p><p>空中英语教室  <a href="http://www.kzyyjs.com/">http://www.kzyyjs.com/</a></p><p>AskMySite <a href="http://www.askmysite.com/">http://www.askmysite.com/</a></p><p>UrbanDictionary  ： <a href="http://www.urbandictionary.com/">http://www.urbandictionary.com/</a></p><p>英语点津  <a href="http://www.chinadaily.com.cn/language_tips/">http://www.chinadaily.com.cn/language_tips/</a></p><p>外语杂志  <a href="http://westmagz.com/default.asp">http://westmagz.com/default.asp</a></p><p>每日英语  <a href="http://blog.beanwoo.com/english">http://blog.beanwoo.com/english</a></p><p>EnglishBaby ： <a href="http://www.englishbaby.com/">http://www.englishbaby.com/</a></p><p>英语聊天室  <a href="http://chatto.us/">http://chatto.us/</a></p><p>米老师  <a href="http://missrice.com/Default.aspx">http://missrice.com/Default.aspx</a></p><h2 id="专四专八"><a href="#专四专八" class="headerlink" title="专四专八"></a>专四专八</h2><p>牛津英语网  <a href="http://www.oxford.com.cn/study/exam/major/">http://www.oxford.com.cn/study/exam/major/</a></p><p>考试大  <a href="http://www.examda.com/TEM/">http://www.examda.com/TEM/</a></p><p>中国英语学习网 <a href="http://www.24en.com/tem/">http://www.24en.com/tem/</a></p><p>沪江网  <a href="http://www.hjenglish.com/down/list/113/">http://www.hjenglish.com/down/list/113/</a></p><p>新挑战国际英语  <a href="http://www.tzcool.com/List2.asp?BClassID=4&amp;SClassID=18">http://www.tzcool.com/List2.asp?BClassID=4&amp;SClassID=18</a></p><p>中国考题网  <a href="http://www.ksw123.com/index_54.shtml">http://www.ksw123.com/index_54.shtml</a></p><p>星沙英语  <a href="http://www.rr365.com/english/List_700.html">http://www.rr365.com/english/List_700.html</a></p><p>大耳朵英语  <a href="http://www.ebigear.com/newslist-122-1.html">http://www.ebigear.com/newslist-122-1.html</a></p><p>真题网  <a href="http://www.pass-e.com/sort.php?sortid=25">http://www.pass-e.com/sort.php?sortid=25</a></p><p>就学网  <a href="http://www.joxue.com/joxue/en/id11/">http://www.joxue.com/joxue/en/id11/</a></p><h2 id="考研信息"><a href="#考研信息" class="headerlink" title="考研信息"></a>考研信息</h2><p>中国研究生招生信息网  <a href="http://www.chinayz.com.cn/">http://www.chinayz.com.cn/</a></p><p>考研网  <a href="http://www.kaoyan.net/">http://www.kaoyan.net/</a></p><p>中国考研网  <a href="http://www.chinakaoyan.com/">http://www.chinakaoyan.com/</a></p><p>考研教育网  <a href="http://www.cnedu.cn/">http://www.cnedu.cn/</a></p><p>21CN 考研 <a href="http://learning.21cn.com/kaoshi/kaoyan/">http://learning.21cn.com/kaoshi/kaoyan/</a></p><p>考研加油站  <a href="http://www.kaoyan.com/">http://www.kaoyan.com/</a></p><p>考研信息港  <a href="http://www.kaoyan365.com/">http://www.kaoyan365.com/</a></p><p>考研论坛  <a href="http://bbs.kaoyan.com/">http://bbs.kaoyan.com/</a></p><p>21 世纪考研网 <a href="http://www.21ky.net/">http://www.21ky.net/</a></p><p>清华考研远程辅导网  <a href="http://www.tsinghuatutor.com/">http://www.tsinghuatutor.com/</a></p><p>考研共济网  <a href="http://www.kaoyantj.com/">http://www.kaoyantj.com/</a></p><p>网大考研  <a href="http://www.netbig.com/exam/ch2.htm">http://www.netbig.com/exam/ch2.htm</a></p><p>考研宝典   <a href="http://www.exambook.net/">http://www.exambook.net/</a></p><p>考研同路人  <a href="http://www.17ky.com/">http://www.17ky.com/</a></p><p>北京考研网  <a href="http://www.010ky.com/">http://www.010ky.com/</a></p><p>研路资讯  <a href="http://www.roadedu.com/">http://www.roadedu.com/</a></p><p>导航考研  <a href="http://www.daohang.net/">http://www.daohang.net/</a></p><p>圣才考研网  <a href="http://www.100exam.com/">http://www.100exam.com/</a></p><p>3COM 免费考研网 <a href="http://kind887.518u.com/">http://kind887.518u.com/</a></p><p>OK 考研网 <a href="http://www.okkaoyan.cn/">http://www.okkaoyan.cn/</a></p><h2 id="留学信息"><a href="#留学信息" class="headerlink" title="留学信息"></a>留学信息</h2><p>教育涉外监管信息网  <a href="http://www.jsj.edu.cn/">http://www.jsj.edu.cn/</a></p><p>国家留学基金委员会  <a href="http://www.csc.edu.cn/gb/">http://www.csc.edu.cn/gb/</a></p><p>经教育部资格认定中介  <a href="http://www.jsj.edu.cn/mingdan/001.html">http://www.jsj.edu.cn/mingdan/001.html</a></p><p>教育部公布的外国学校  <a href="http://www.jsj.edu.cn/mingdan/004.html">http://www.jsj.edu.cn/mingdan/004.html</a></p><p>世纪出国资讯易网  <a href="http://www.21abroad.net/">http://www.21abroad.net/</a></p><p>北京留学网  <a href="http://www.bjlx.gov.cn/">http://www.bjlx.gov.cn/</a></p><p>中国留学人才信息网  <a href="http://www.chinatalents.gov.cn/">http://www.chinatalents.gov.cn/</a></p><p>艾迪国际  <a href="http://www.studyoz.com.cn/">http://www.studyoz.com.cn/</a></p><p>东方移民留学中心  <a href="http://www.visa2au.com/">http://www.visa2au.com/</a></p><p>国际教育留学资讯网  <a href="http://www.internationaledu.net/">http://www.internationaledu.net/</a></p><p>北京环球行留学服务  <a href="http://www.wefedu.com/">http://www.wefedu.com/</a></p><p>自在留学网  <a href="http://www.igoedu.com/">http://www.igoedu.com/</a></p><p>留学第一站  <a href="http://www.globeedu.com/">http://www.globeedu.com/</a></p><p>北京嘉华世达国际教育中心  <a href="http://www.chivast.com/">http://www.chivast.com/</a></p><p>中国教育服务中心  <a href="http://www.cesc.com.cn/">http://www.cesc.com.cn/</a></p><p>中教国际教育交流中心  <a href="http://www.cciee.com.cn/">http://www.cciee.com.cn/</a></p><p>高士登留学  <a href="http://www.gsdedu.com/">http://www.gsdedu.com/</a></p><p>DIY 留学法国 <a href="http://www.francediy.org/">http://www.francediy.org/</a></p><p>中国对外友好合作服务  <a href="http://www.youhao.net.cn/">http://www.youhao.net.cn/</a></p><p>中国出国人员服务总公司  <a href="http://www.cnsc-edu.com.cn/">http://www.cnsc-edu.com.cn/</a></p><h2 id="公务员考试"><a href="#公务员考试" class="headerlink" title="公务员考试"></a>公务员考试</h2><p>中国人事考试网  <a href="http://www.cpta.com.cn/">http://www.cpta.com.cn/</a></p><p>中国海关考录网  <a href="http://kaolu.customs.gov.cn/">http://kaolu.customs.gov.cn/</a></p><p>北京市人事考试网  <a href="http://www.bjpta.gov.cn/">http://www.bjpta.gov.cn/</a></p><p>中华人民共和国人事部  <a href="http://www.mop.gov.cn/">http://www.mop.gov.cn/</a></p><p>公务员考试指南针  <a href="http://www.softunnel.com/compass.htm">http://www.softunnel.com/compass.htm</a></p><p>国家公务员考试 _ 新浪 <a href="http://edu.sina.com.cn/focus/official.html">http://edu.sina.com.cn/focus/official.html</a></p><p>公务员考试 _ 新华网 <a href="http://www.xinhuanet.com/zhengfu/gwy/">http://www.xinhuanet.com/zhengfu/gwy/</a></p><p>公务员考试 _ 中招在线 <a href="http://www.yuloo.com/gwyks/">http://www.yuloo.com/gwyks/</a></p><p>腾讯公务员考试  <a href="http://edu.qq.com/official/">http://edu.qq.com/official/</a></p><p>公务员考试 _ 南开大学 <a href="http://career.nankai.edu.cn/official/">http://career.nankai.edu.cn/official/</a></p><p>公务员考试 _ 济宁信息港 <a href="http://edu.jninfo.net.cn/gwyks/">http://edu.jninfo.net.cn/gwyks/</a></p><p>福建录用公务员考试网  <a href="http://www.fjkl.gov.cn/">http://www.fjkl.gov.cn/</a></p><p>广东公务员考试网  <a href="http://www.gdgwy.net/">http://www.gdgwy.net/</a></p><p>广州人事信息网  <a href="http://www.gzpi.gov.cn/">http://www.gzpi.gov.cn/</a></p><h2 id="司法考试"><a href="#司法考试" class="headerlink" title="司法考试"></a>司法考试</h2><p>中国普法网 ( 司法部 ) <a href="http://www.legalinfo.gov.cn/">http://www.legalinfo.gov.cn/</a></p><p>法律教育网  <a href="http://www.chinalawedu.com/">http://www.chinalawedu.com/</a></p><p>中国司法考试在线  <a href="http://www.sifa2000.com/">http://www.sifa2000.com/</a></p><p>国家司法考试在线  <a href="http://www.sikao.com/">http://www.sikao.com/</a></p><p>国家司法考试网  <a href="http://www.bjsfj.com/">http://www.bjsfj.com/</a></p><p>律政中国司法考试网  <a href="http://www.lzschool.org.cn/">http://www.lzschool.org.cn/</a></p><p>全国司法考试试题辅导  <a href="http://www.sifakaoshi.net/">http://www.sifakaoshi.net/</a></p><p>司法统一考试  <a href="http://www.sftyks.com/">http://www.sftyks.com/</a></p><p>国家司法考试 _ 新浪网 <a href="http://edu.sina.com.cn/focus/lawyer.html">http://edu.sina.com.cn/focus/lawyer.html</a></p><p>万国司法考试  <a href="http://www.wanguoschool.net/">http://www.wanguoschool.net/</a></p><p>广州国家司法考试网  <a href="http://www.gzsk.gov.cn/">http://www.gzsk.gov.cn/</a></p><p>司法人  <a href="http://www.lawee.com.cn/">http://www.lawee.com.cn/</a></p><p>国家司法考试辅导培训  <a href="http://www.peixunwang.com/">http://www.peixunwang.com/</a></p><h2 id="计算机等级考试"><a href="#计算机等级考试" class="headerlink" title="计算机等级考试"></a>计算机等级考试</h2><p>全国计算机等级考试网  <a href="http://www.ncre.cn/">http://www.ncre.cn/</a></p><p>等级考试 _ 无忧服务站 <a href="http://www.wuyouschool.com.cn/">http://www.wuyouschool.com.cn/</a></p><p>信息产业部电子教育  <a href="http://www.ceiaec.org/">http://www.ceiaec.org/</a></p><p>思达网校 _IT 认证社区 <a href="http://www.staredu.net/">http://www.staredu.net/</a></p><p>软件水平考试  <a href="http://www.exam100.com/">http://www.exam100.com/</a></p><p>世纪软考  <a href="http://www.softexam.net/">http://www.softexam.net/</a></p><h2 id="人才招聘"><a href="#人才招聘" class="headerlink" title="人才招聘"></a>人才招聘</h2><p>高校毕业生网  <a href="http://www.myjob.edu.cn/">http://www.myjob.edu.cn/</a></p><p>中国高校就业联盟网  <a href="http://www.job9151.com/">http://www.job9151.com/</a></p><p>中国大学生就业见习网  <a href="http://www.54club.com/">http://www.54club.com/</a></p><p>北京市毕业生就业信息网  <a href="http://www.bjbys.com/">http://www.bjbys.com/</a></p><p>北京毕业生就业指导中心  <a href="http://www.bjbys.net.cn/">http://www.bjbys.net.cn/</a></p><p>北京毕业生就业中心  <a href="http://www.bjbys.net.cn/">http://www.bjbys.net.cn/</a></p><p>研究生人才网  <a href="http://www.91student.com/">http://www.91student.com/</a></p><p>智联招聘网   <a href="http://www.zhaopin.com/">http://www.zhaopin.com/</a> 全国，但以北京信息最多</p><p>中华英才网  <a href="http://www.chinahr.com/">http://www.chinahr.com</a></p><p>51job  <a href="http://www.51job.com/">http://www.51job.com/</a>     信息较多的是北京、上海、深圳、广州</p><p>中国俊才网 <a href="http://www.goodjob.cn/">http://www.goodjob.cn/</a> </p><p>易才网  <a href="http://www.job1998.com/">http://www.job1998.com/</a></p><p>易之易工作网  <a href="http://www.e2ejob.com/">http://www.e2ejob.com/</a></p><p>每日人才网  <a href="http://www.rc365.com/">http://www.rc365.com/</a></p><p>58 城网 - 兼职 <a href="http://www.58.com/jianzhi.aspx">http://www.58.com/jianzhi.aspx</a></p><p>中国经理人才网  <a href="http://www.m-jobcn.com/">http://www.m-jobcn.com/</a></p><p>HR 伴侣 <a href="http://www.hrbanlv.com/">http://www.hrbanlv.com/</a></p><p>中国人力资源联盟  <a href="http://www.hrsou.cn/">http://www.hrsou.cn/</a></p><p>智通人才招聘网  <a href="http://www.job5156.com/">http://www.job5156.com/</a></p><p>应届生求职网： <a href="http://yingjiesheng.com/">http://yingjiesheng.com/</a></p><p>中国招聘网： <a href="http://www.500zhaopin.com/">http://www.500zhaopin.com</a>  500 强企业招聘大型人才网，外企招聘和校园</p><p>招聘都有，以北京，上海，广东信息最多 .</p><p>校园招聘网 <a href="http://www.xyzp.net/">http://www.xyzp.net</a> 也是一个自动抓取各个学校就业中心信息的信</p><p>息汇总网站 .</p><h2 id="简历无忧"><a href="#简历无忧" class="headerlink" title="简历无忧"></a>简历无忧</h2><p>中国电子简历网  <a href="http://www.chinacv.net/">http://www.chinacv.net/</a></p><p>中国简历网  <a href="http://www.5520.org/">http://www.5520.org/</a></p><p>简历吧  <a href="http://www.resume8.com/">http://www.resume8.com/</a></p><p>中国人才指南网  <a href="http://www.cnrencai.com/">http://www.cnrencai.com/</a></p><p>简历中国  <a href="http://www.jlchina.cn/">http://www.jlchina.cn/</a></p><p>轻松简历网  <a href="http://www.easyresume.net/">http://www.easyresume.net/</a></p><p>中英文简历工作室  <a href="http://www.mycvcv.com/">http://www.mycvcv.com/</a></p><p>中国个人简历网  <a href="http://www.t135.com/">http://www.t135.com/</a></p><p>世纪简历网  <a href="http://www.21ren.com/">http://www.21ren.com/</a></p><p>中国求职简历网  <a href="http://www.jianli-sky.com/">http://www.jianli-sky.com/</a></p><p>兼职、实习、求职网站信息大全</p><p>首先，确定你的行业，和最关注的企业，把自己的简历放到人家的官方网站上（如 IBM 的官方招聘网址为 <a href="http://www-07.ibm.com/employment/cn/index.html">http://www-07.ibm.com/employment/cn/index.html</a> ），然后定期去心仪企业的网站察看最新职位，并申请！</p><p>其次，大多数的著名外企都会在以下最权威网站（如果时间有限就看这四个就够用了）发布自己的招聘职位和申请流程，</p><p><a href="http://www.chinahr.com/">http://www.chinahr.com</a></p><p><a href="http://www.51job.com/">http://www.51job.com</a></p><p><a href="http://www.zhaopin.com/">http://www.zhaopin.com</a></p><p><a href="http://www.fesco.com.cn/">http://www.fesco.com.cn</a> 实习和全职都有，希望大家每日 / 每周关注，一定会对自己的职业发展有帮助的！</p><h2 id="补充一些有用的网站"><a href="#补充一些有用的网站" class="headerlink" title="补充一些有用的网站"></a>补充一些有用的网站</h2><p>1 ， <a href="http://www.shixi.com.cn/">http://www.shixi.com.cn/</a> 中国实习网（刚刚起步，信息不多） </p><p>2, <a href="http://www.edeng.cn/data/china/job/index.html?r=34892">http://www.edeng.cn/data/china/job/index.html?r=34892</a> 易登兼职频道 ( 兼职实习信息较多，更新快 )</p><p>3 ， <a href="http://job.xsup.cn/">http://job.xsup.cn/</a> 学生新势力 ( 注册会员免费 , 信息更新还不错 )</p><p>4 ， <a href="http://www.gzjianzhi.com/">http://www.gzjianzhi.com/</a> 广州子凡兼职网 ( 需要注册为会员才能查看信息。注册会员免费 )</p><p>5 ， <a href="http://scc.pku.edu.cn/sub.asp">http://scc.pku.edu.cn/sub.asp</a> 北大就业信息网实习频道（可直接访问） </p><p>6 ， <a href="http://www.020stu.com/job/index.asp">http://www.020stu.com/job/index.asp</a> 广州学生网兼职 </p><p>7 ， <a href="http://www.gzca.com.cn/bbs/index.asp">http://www.gzca.com.cn/bbs/index.asp</a> 广州高校论坛兼职 </p><p>8 ， <a href="http://www.rmzp.com/">http://www.rmzp.com/</a> 人脉招聘网（找实习人脉还是很重要的） </p><p>9 ， <a href="http://www.54club.com/">http://www.54club.com</a> 中国大学生就业见习网 </p><p>10 ， <a href="http://bbs.pku.edu.cn/">http://bbs.pku.edu.cn/</a> 未名的实习版 </p><p>11 ， <a href="http://www.cnshixi.com/">http://www.cnshixi.com/</a> 中国实习网（竟然重名了，呵呵，广东地区信息较多） </p><p>12 ， <a href="http://www.globehr.com/">http://www.globehr.com/</a> 搜职网（自动搜索招聘信息，实习职位偏少） </p><p>13 ， <a href="http://www.jobok.com.cn/">http://www.jobok.com.cn/</a> 中国兼职网 </p><p>14 ， <a href="http://www.conningtech.com/index.php">http://www.conningtech.com/index.php</a> 大学生兼职网 </p><p>15 ， <a href="http://www.raya.cn/job/city_index.php">http://www.raya.cn/job/city_index.php</a> 瑞雅网兼职频道 </p><p>16 ， <a href="http://www.haojz.com/index.asp">http://www.haojz.com/index.asp</a> 广州家政网 </p><p>17 ， <a href="http://www.cnshixi.com/index.asp">http://www.cnshixi.com/index.asp</a> 大学生实习网</p><p>另可参考以下渠道：</p><p>毕业生必须知道的就业信息渠道 !!!!</p><h2 id="毕业生必须知道的就业信息渠道"><a href="#毕业生必须知道的就业信息渠道" class="headerlink" title="毕业生必须知道的就业信息渠道"></a>毕业生必须知道的就业信息渠道</h2><p>1  校就业指导中心－－校就业网 ,bbs- 走向社会</p><p>2  院系学工办   －－信件，电话通知等方式</p><p>3  各班班长－－通知本人</p><p>4  北京大学就业网－只可以看到目录－将目录输入到“百度”搜索</p><p>5 除北京大学、人民大学无法直接进入查看信息外，其他大多数大学就业网都可以直</p><p>接进入，如清华大学就业网－－可以随意进入</p><p>请大家注意保留，以下就业网可以随便进入不需要身份验证！</p><p>同济大学： <a href="http://tj91.tongji.edu.cn/index.portal#">http://tj91.tongji.edu.cn/index.portal#</a></p><p>西北大学： <a href="http://news.nwu.edu.cn/nwujobcizi/">http://news.nwu.edu.cn/nwujobcizi/</a></p><p>哈工大   ： <a href="http://som.hit.edu.cn/glxyxgb01/sub.asp?no=7">http://som.hit.edu.cn/glxyxgb01/sub.asp?no=7</a></p><p>东南大学： <a href="http://xsc.seu.edu.cn/bf/introCo">http://xsc.seu.edu.cn/bf/introCo</a> … Key2=&amp;Post=Post</p><p>华东师范： <a href="http://www.career.ecnu.edu.cn/commonpage/in">http://www.career.ecnu.edu.cn/commonpage/in</a> ｆｒｏｍ ation.aspx</p><p>北京大学： <a href="http://scc.pku.edu.cn/sub.asp?id=8">http://scc.pku.edu.cn/sub.asp?id=8</a></p><p>清华大学： <a href="http://scc.pku.edu.cn/sub.asp?id=8">http://scc.pku.edu.cn/sub.asp?id=8</a></p><p>中国农大： <a href="http://scc.cau.edu.cn/Zp/zpxx.aspx">http://scc.cau.edu.cn/Zp/zpxx.aspx</a></p><p>北京师大： <a href="http://202.112.92.112/">http://202.112.92.112/</a></p><p>offer 收割机： <a href="http://offer.xyzp.net/">http://offer.xyzp.net</a></p><p>北京高校毕业生信息网： <a href="http://scc.cau.edu.cn/Zp/zpxx.aspx">http://scc.cau.edu.cn/Zp/zpxx.aspx</a></p><p>长三角人才网： <a href="http://www.job360.com/">http://www.job360.com/</a></p><p>天津人才网： <a href="http://www.tjrc.com.cn/">http://www.tjrc.com.cn/</a></p><p>江苏人才： <a href="http://www.jsrsrc.com/">http://www.jsrsrc.com/</a></p><p>南京人才： <a href="http://www.njrsrc.com/">http://www.njrsrc.com/</a></p><p>浙江人才  <a href="http://www.zjrc.com/">www.zjrc.com</a></p><p>杭州人才  <a href="http://www.hzrc.com/">www.hzrc.com</a></p><p>中华英才： <a href="http://www.chinahr.com/">www.chinahr.com</a></p><p>智联招聘： <a href="http://www.zhaopin.com/">www.zhaopin.com</a></p><p>前程无忧： <a href="http://www.51job.com/">www.51job.com</a></p><p>校园招聘一网打尽，好多学校 bbs 的招聘信息： <a href="http://www.xyzp.net/">http://www.xyzp.net/</a></p><p>数字英才： <a href="http://www.01hr.com/">http://www.01hr.com/</a></p><p>中聘网： <a href="http://www.pincn.com/">http://www.pincn.com/</a></p><p>中国青年人才网： <a href="http://www.54job.com/">http://www.54job.com/</a></p><p>中国校园招聘网： <a href="http://www.91job.net.cn/">http://www.91job.net.cn/</a></p><p>中国高校毕业生就业信息网： <a href="http://www.myjob.edu.cn/">http://www.myjob.edu.cn/</a></p><p>高校毕业生就业联盟： <a href="http://www.job9151.com/t_index.asp">http://www.job9151.com/t_index.asp</a></p><p>中国企业人才网： <a href="http://www.job100.com/default.asp">http://www.job100.com/default.asp</a></p><p>中国校园网： <a href="http://www.54youth.com.cn/">http://www.54youth.com.cn/</a></p><p>研究生人才网： <a href="http://www.91student.com/">http://www.91student.com/</a></p><p>地方性的有：</p><p>得得人才网： <a href="http://www.dedejob.com/">http://www.dedejob.com</a> 全国，北京上海为主；</p><p>上海人才网： <a href="http://www.001hr.net/">http://www.001hr.net</a> 上海及浙江、江苏东；</p><p>上海人才市场： <a href="http://www.hr.net.cn/">http://www.hr.net.cn</a> 上海</p><p>广州人才网： <a href="http://www.020job.com/">http://www.020job.com</a> 广州及周边</p><p>128 人才网： <a href="http://www.job128.com/">http://www.job128.com</a> 广东、北京</p><p>北京科技人才网： <a href="http://www.bjkjrc.com/">http://www.bjkjrc.com</a> 北京</p><p>另外转载：</p><p>1 ， <a href="http://intern.hiall.com.cn/">http://intern.hiall.com.cn</a> Hiall 实习社区（隆重推荐！！！）</p><p>2 ， <a href="http://scc.pku.edu.cn/sub.asp?id=9">http://scc.pku.edu.cn/sub.asp?id=9</a> 北大就业信息网实习频道（可直接访问）</p><p>3 ， <a href="http://jx.edu.sina.com.cn/">http://jx.edu.sina.com.cn/</a> 54club （上海地区的职位偏多）</p><p>4 ， <a href="http://www3.newsmth.com/bbsdoc.php?board=Intern">http://www3.newsmth.com/bbsdoc.php?board=Intern</a> 水木实习版（技术类职位多）</p><p>5 ， <a href="http://bbs.ruc.edu.cn/bbsdoc.php?board=intern">http://bbs.ruc.edu.cn/bbsdoc.php?board=intern</a> 人大实习版（外校不好上）</p><p>6 ， <a href="http://www.shixi.com.cn/">http://www.shixi.com.cn/</a> 中国实习网（刚刚起步，信息不多）</p><p>7 ， <a href="http://www.cnshixi.com/">http://www.cnshixi.com/</a> 中国实习网（竟然重名了，呵呵，广东地区信息较多）</p><p>8 ， <a href="http://www.globehr.com/">http://www.globehr.com/</a> 搜职网（自动搜索招聘信息）</p><p>9 ， <a href="http://www.tianji.com/">http://www.tianji.com/</a> 天际网（很多牛师兄师姐在上面，人脉求职）</p><p><a href="http://career.em.tsinghua.edu.cn/">http://career.em.tsinghua.edu.cn</a>  清华经管职业发展网</p><p>电气、电信、通讯专业王牌专业课程汇总</p><p><a href="http://blog.xiaonei.com/GetEntry.do?id=315442669&amp;owner=236620117">http://blog.xiaonei.com/GetEntry.do?id=315442669&amp;owner=236620117</a></p>]]></content>
    
    
    <categories>
      
      <category>技术分享</category>
      
    </categories>
    
    
    <tags>
      
      <tag>技术分享</tag>
      
      <tag>学习</tag>
      
      <tag>网站</tag>
      
    </tags>
    
  </entry>
  
  
  
  <entry>
    <title>数据结构预备知识</title>
    <link href="/2022/01/27/%E7%AC%94%E8%AE%B0/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E9%A2%84%E5%A4%87%E7%9F%A5%E8%AF%86/"/>
    <url>/2022/01/27/%E7%AC%94%E8%AE%B0/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E9%A2%84%E5%A4%87%E7%9F%A5%E8%AF%86/</url>
    
    <content type="html"><![CDATA[<h1 id="一、C语言常识"><a href="#一、C语言常识" class="headerlink" title="一、C语言常识"></a>一、C语言常识</h1><ul><li>C程序规定一个程序中有<strong>一个或多个函数</strong>，他们是C程序的基本模块。但必须有且<strong>只有一个main函数</strong>。</li><li>C程序的执行将从main函数开始，到main函数结束而停止。 </li><li>main()是一个函数的名字,括号里面的<strong>void表示空的</strong>，这里指<strong>不接受任何参数</strong>。</li><li>只需要把int和void看作是用来定义<strong>main()函数的标准</strong>即可</li></ul><span id="more"></span><figure class="highlight c"><table><tr><td class="gutter"><div class="code-wrapper"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></div></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;stdio.h&gt;</span>                 <span class="hljs-comment">/*#include语句是C预处理指令，引入标准输入输出头文件*/</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">(<span class="hljs-keyword">void</span>)</span>                  <span class="hljs-comment">/*主函数，前面的int指明main()函数的返回类型为整数（integer）*/</span></span><br><span class="hljs-function"></span>&#123;<br>    <span class="hljs-keyword">int</span> number;            <span class="hljs-comment">/*定义个名字叫做number的变量，C语言中所有变量必须在使用前定义*/</span><br>    number=<span class="hljs-number">2021</span>;                <span class="hljs-comment">/*给number赋一个值*/</span><br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;Hello ! I am a person.\n&quot;</span>);    <span class="hljs-comment">/*调用printf()函数，将引号中间的内容显示到屏幕上*/</span><br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;This year is %d\n&quot;</span>,number); <span class="hljs-comment">//%d占位符，表示输出number值的位置和形式(十进制)</span><br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<span class="hljs-comment">//返回值，只需理解为这是满足C的标准要求</span><br>&#125;<br><br>运行结果：<br>Hello ! I am a person.<br>This year is <span class="hljs-number">2021</span><br></code></pre></td></tr></table></figure><p>C语言的重要性就不多说，学习编程，实践很重要，学校OJ的网址<a href="http://acm.zzuli.edu.cn/">ZZULIOJ</a>，咱们学校考研复试也要C语言上机，重点就是前200道题。比如题目编号1000，整数a+b，最简单入门的一道题，计算两个整数的和。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;stdio.h&gt;</span><span class="hljs-comment">//标准输入输出</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span><br><span class="hljs-function"></span>&#123;<br><span class="hljs-keyword">int</span> a,b,c;<br> <span class="hljs-built_in">scanf</span>(<span class="hljs-string">&quot;%d %d&quot;</span>,&amp;a,&amp;b);<span class="hljs-comment">//读入a和b</span><br>c=a+b;<span class="hljs-comment">//计算a+b的值赋给c</span><br><span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%d&quot;</span>,c);<span class="hljs-comment">//输出c</span><br><span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>注意到scanf读入数据的时候需要加&amp;取地址符，而printf输出数据的时候却不用，想一想为什么？</p><p>因为scanf要往你的变量里写入数值，所以他必须知道那个变量的地址，至于变量里存的是什么值，他是不管的，反正他写入之后就被覆盖成新的值了<br>对比printf，他是要输出变量里的数值，他只管要那个值，至于地址在哪，他也无所谓<br>这就是写和读的本质性区别，<strong>写只要地址，读只要值</strong></p><p>变量其实同时有地址和值两个东西，我们一般用一个变量，都是直接写一个名字，其实如果这个名字在赋值号右边，就是代表值，如果在赋值号左边，就是代表地址，写出来一样，意义是不一样的，编译器自动帮你选择了正确的意义<br>变量名字写在函数参数里面时，和写在赋值号右边一样，也是代表值，可是像scanf这种函数，他确实需要地址，编译器只认识赋值号，不认识scanf，没法自动选到正确的东西，这时就需要你手动加一个取地址的符号&amp;，明确告诉编译器去选择变量的地址给这个scanf来用。</p><blockquote><p>关于地址或指针的知识，后面也会详细介绍。</p></blockquote><h2 id="For循环"><a href="#For循环" class="headerlink" title="For循环"></a>For循环</h2><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-keyword">int</span> i, sum=<span class="hljs-number">0</span>;<br>    <span class="hljs-keyword">for</span>(i=<span class="hljs-number">1</span><span class="hljs-comment">/*语句①*/</span>; i&lt;=<span class="hljs-number">100</span><span class="hljs-comment">/*语句②*/</span>; i++<span class="hljs-comment">/*语句③*/</span>)&#123;<br>        sum+=i;<br>    &#125;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%d\n&quot;</span>,sum);<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-keyword">for</span>(表达式<span class="hljs-number">1</span>; 表达式<span class="hljs-number">2</span>; 表达式<span class="hljs-number">3</span>)&#123;<br>  语句块<br>&#125;<br></code></pre></td></tr></table></figure><p>它的运行过程为：</p><ol><li><p>先执行“表达式1”。</p></li><li><p>再执行“表达式2”，如果它的值为真（非0），则执行循环体，否则结束循环。</p></li><li><p>执行完循环体后再执行“表达式3”。</p></li><li><p>重复执行步骤 2) 和 3)，直到“表达式2”的值为假，就结束循环。</p></li></ol><p>上面的步骤中，2) 和 3) 是一次循环，会重复执行，for 语句的主要作用就是不断执行步骤 2) 和 3)。</p><p>“表达式1”仅在第一次循环时执行，以后都不会再执行，可以认为这是一个初始化语句。“表达式2”一般是一个关系表达式，决定了是否还要继续下次循环，称为“循环条件”。“表达式3”很多情况下是一个带有自增或自减操作的表达式，以使循环条件逐渐变得“不成立”。</p><h1 id="二、数组"><a href="#二、数组" class="headerlink" title="二、数组"></a>二、数组</h1><p>把数据放入内存，必须先要分配内存空间。放入4个整数，就得分配4个<code>int</code>类型的内存空间：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-keyword">int</span> a[<span class="hljs-number">4</span>];<br></code></pre></td></tr></table></figure><p>这样，就在内存中分配了4个<code>int</code>类型的内存空间，共 4×4=16 个字节，并为它们起了一个名字，叫<code>a</code>。</p><p>访问数组元素的格式为：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c">a[index]<br></code></pre></td></tr></table></figure><p>index 为数组下标。注意 index 的值必须大于等于零，并且小于数组长度，否则会发生<strong>数组越界</strong>，出现意想不到的错误，</p><p>当赋予数组的元素个数超过数组长度时，就会发生<strong>溢出（Overflow）</strong>。如下所示：</p><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-attribute">int</span> a[<span class="hljs-number">3</span>] = &#123;<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>&#125;;<br></code></pre></td></tr></table></figure><p>数组长度为3，初始化时却赋予5个元素，超出了数组容量，所以只能保存前3个元素，后面的元素被丢弃。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-keyword">int</span> a[<span class="hljs-number">100</span>];     <span class="hljs-comment">//定义一个数组名为a，存储100个int类型的数组,其元素分别是a[0]~a[99]</span><br><span class="hljs-keyword">float</span> b[<span class="hljs-number">10</span>];    <span class="hljs-comment">//数组名为b的，存储10个float类型的数组,其元素分别是b[0]~b[9]</span><br><span class="hljs-keyword">char</span> c[<span class="hljs-number">256</span>]；    <span class="hljs-comment">//定义一个数组名为c的字符型数组 长度为256,其元素分别是c[0]~c[255]</span><br></code></pre></td></tr></table></figure><ul><li><strong>数组</strong>是一个整体，它的<strong>内存是连续</strong>的；也就是说，数组元素之间是相互挨着的，彼此之间没有一点点缝隙。</li><li>一般情况下，<strong>数组名</strong>会转换为数组的<strong>地址</strong>，需要使用地址的地方，直接使用数组名即可</li><li>数组中的每个元素都有一个序号，这个序号<strong>从0开始</strong>，而不是从1开始，称为<strong>下标（Index）</strong></li><li>数组中每个元素的<strong>数据类型必须相同</strong>，对于<code>int a[4];</code>，每个元素都必须为 int。</li></ul><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-comment">//定义的时候初始化</span><br><br><span class="hljs-comment">//定义一个整型数组a，前5个元素即赋值为1，2，3，4，5,后95个元素值值全部为0</span><br><span class="hljs-keyword">int</span> a[<span class="hljs-number">100</span>]=&#123;<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>&#125;; <br><br><span class="hljs-comment">//定义float数组b并对全部float类型的元素都分别赋值</span><br><span class="hljs-keyword">float</span> b[<span class="hljs-number">10</span>]=&#123;<span class="hljs-number">1.1</span>,<span class="hljs-number">2.2</span>,<span class="hljs-number">3.3</span>,<span class="hljs-number">4.4</span>,<span class="hljs-number">5.5</span>,<span class="hljs-number">6.6</span>,<span class="hljs-number">7.7</span>,<span class="hljs-number">8.8</span>,<span class="hljs-number">9.9</span>,<span class="hljs-number">0.0</span>&#125;;  <br><br><span class="hljs-comment">//定义一个数组名为c的字符型数组 并对前9个元素进行赋值，其余元素全部为&#x27;\0&#x27;</span><br><span class="hljs-comment">//&#x27;\0&#x27;是字符串结束的标志</span><br><span class="hljs-keyword">char</span> c[<span class="hljs-number">256</span>]=&#123;<span class="hljs-string">&#x27;C&#x27;</span>,<span class="hljs-string">&#x27;l&#x27;</span>,<span class="hljs-string">&#x27;a&#x27;</span>,<span class="hljs-string">&#x27;n&#x27;</span>,<span class="hljs-string">&#x27;g&#x27;</span>,<span class="hljs-string">&#x27;u&#x27;</span>,<span class="hljs-string">&#x27;a&#x27;</span>,<span class="hljs-string">&#x27;g&#x27;</span>,<span class="hljs-string">&#x27;e&#x27;</span>&#125;;<br></code></pre></td></tr></table></figure><img src="https://s2.loli.net/2022/01/27/MDe6nN4CFtZH2bl.png" alt="image-20210809122403782" style="zoom:50%;" /> <figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-keyword">char</span> str[<span class="hljs-number">7</span>] = <span class="hljs-string">&quot;abc123&quot;</span>;<br></code></pre></td></tr></table></figure><p>在C语言中，字符串总是以<code>&#39;\0&#39;</code>作为结尾，所以<code>&#39;\0&#39;</code>也被称为字符串结束标志，或者字符串结束符。</p><p><code>&quot;abc123&quot;</code>看起来只包含了 6 个字符，我们却将 str 的长度定义为 7，就是为了能够容纳最后的<code>&#39;\0&#39;</code>。如果将 str 的长度定义为 6，它就无法容纳<code>&#39;\0&#39;</code>了</p><h1 id="三、C语言指针"><a href="#三、C语言指针" class="headerlink" title="三、C语言指针"></a>三、C语言指针</h1><h2 id="1-数据类型"><a href="#1-数据类型" class="headerlink" title="1.数据类型"></a>1.数据类型</h2><h3 id="1-1-为什么要用数据类型？"><a href="#1-1-为什么要用数据类型？" class="headerlink" title="1.1    为什么要用数据类型？"></a>1.1    为什么要用数据类型？</h3><p>答：数据类型用来说明数据的类型，确定了数据的解释方式，让计算机和程序员不会产生歧义</p><p>因为对于不同的对象，不同的数据类型更具有代表性</p><p>为了合理地利用空间， 将数据分为多种数据类型</p><p>基本类型：char     short    int    long    float    </p><h3 id="1-2-为什么int占4个字节？（32位）"><a href="#1-2-为什么int占4个字节？（32位）" class="headerlink" title="1.2    为什么int占4个字节？（32位）"></a>1.2    为什么int占4个字节？（32位）</h3><p>答：可以说是微软规定好的，一个字节(byte)等于8位bit,因为计算机只认识0和1，所以一个字节的长度为2的八次方，</p><p>4个字节就是2的32次方   所以最大值为2的32次方-1=4294967295</p><h3 id="1-3-int数据类型的取值范围是多少？"><a href="#1-3-int数据类型的取值范围是多少？" class="headerlink" title="1.3    int数据类型的取值范围是多少？"></a>1.3    int数据类型的取值范围是多少？</h3><p>答：32位无符号整数 ， 其表示范围是2的32次方，最大整数为 2的32次方-1，（最小数是32位每一位都是0，因此减1）</p><p>有符号数则要去除一个符号位，正数最大为2的31次方-1 , 负数最小为负 2的31次方 </p><img src="https://s2.loli.net/2022/01/27/Y9UD8J7KWSAIMdu.png" alt="image-20210808082138470" style="zoom: 50%;" /> <h3 id="1-4-数据类型长度-sizeof-运算符"><a href="#1-4-数据类型长度-sizeof-运算符" class="headerlink" title="1.4 数据类型长度 sizeof()运算符"></a>1.4 数据类型长度 sizeof()运算符</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-comment">//sizeof运算符，用来求某一类型变量的长度</span><br><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdlib.h&gt;</span><span class="hljs-comment">//standard library标准库头文件</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span><br><span class="hljs-function"></span>&#123;<br>    <span class="hljs-keyword">char</span> ch;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;sizeof(ch)=%d\n&quot;</span>, <span class="hljs-keyword">sizeof</span>(ch));<span class="hljs-comment">//sizeof以字节为单位返回某操作数的大小</span><br>    <br>    <span class="hljs-keyword">int</span> num;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;sizeof(num)=%d\n&quot;</span>, <span class="hljs-keyword">sizeof</span>(num));<br>&#125;<br></code></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-keyword">sizeof</span>(ch)=<span class="hljs-number">1</span><br><span class="hljs-keyword">sizeof</span>(num)=<span class="hljs-number">4</span><br></code></pre></td></tr></table></figure><img src="https://s2.loli.net/2022/01/27/4EnUP19jiBI7pzx.png" alt="image-20210808085950929" style="zoom:50%;" /> <p><strong>数据类型占内存的位数实际上与操作系统的位数和编译器（不同编译器支持的位数可能有所不同）都有关</strong>，具体某种数据类型占字节数得编译器根据操作系统位数两者之间进行协调好后分配内存大小。具体在使用的时候如想知道具体占内存的位数通过**sizeof(int)**可以得到准确的答案</p><p>1B = 8b    一个小b只能存放0或1</p><h2 id="2-内存"><a href="#2-内存" class="headerlink" title="2. 内存"></a>2. 内存</h2><h3 id="2-1-内存是什么？"><a href="#2-1-内存是什么？" class="headerlink" title="2.1 内存是什么？"></a>2.1 内存是什么？</h3><img src="https://s2.loli.net/2022/01/27/c5HUyXx4gGdKSCn.png" alt="image-20210808090435024" style="zoom: 67%;" /><img src="https://s2.loli.net/2022/01/27/Kf9iaeE2HJAIy3O.png" alt="image-20210808091003155" style="zoom:50%;" /> <h3 id="2-2-为什么计算机需要内存？"><a href="#2-2-为什么计算机需要内存？" class="headerlink" title="2.2 为什么计算机需要内存？"></a>2.2 为什么计算机需要内存？</h3><p>那是因为计算机上的<strong>CPU中央处理器</strong>需要不断处理电脑硬盘上的数据，</p><p>但是CPU速度太快，动辄几Ghz，而<strong>硬盘速度太慢</strong>，传输速度才不到200mb/s，延迟还大，即使是固态硬盘也差的很远，完全无法跟上CPU的处理速度，这样必然会导致<strong>性能下降</strong>。</p><p>于是工程师就在cpu中设计了<strong>缓存</strong>，一二三级缓存充当了数据临时仓库的作用，而且速度很快，但是受限于成本和CPU面积，这个<strong>缓存空间很有限</strong>，根本放不开多少数据，于是就在CPU缓存和硬盘之间又加入了新的存储器：<strong>内存</strong>。</p><h3 id="2-3-内存地址"><a href="#2-3-内存地址" class="headerlink" title="2.3 内存地址"></a>2.3 内存地址</h3><p>内存的管理：将内存抽象成一个很大的一维数组</p><p>对内存中每一个字节分配一个32位或64位的编号（与32位或64位处理器有关）</p><p>这个编号我们称之为<strong>内存地址</strong></p><img src="https://s2.loli.net/2022/01/27/vmakyGLFefpcSJ6.png" alt="image-20210808092812590" style="zoom:50%;" />    <p>char：占一个字节，分配一个地址</p><p>int：占四个字节，分配四个地址</p><h3 id="2-4-为什么内存地址以字节为单位？"><a href="#2-4-为什么内存地址以字节为单位？" class="headerlink" title="2.4 为什么内存地址以字节为单位？"></a>2.4 为什么内存地址以字节为单位？</h3><p>根据内存的物理结构，<strong>因为在内存中最小单位就是字节。所以操作系统在管理它的时候，最小单位也就是字节了</strong></p><h2 id="3-C语言指针"><a href="#3-C语言指针" class="headerlink" title="3. C语言指针"></a>3. C语言指针</h2><p>计算机中所有的数据都必须放在<strong>内存</strong>中运行，不同类型的数据占用的字节数不一样，例如 int 占用 4 个字节。为了正确地访问这些数据，必须为每个字节都编上号码。</p><p>下图是 4G 内存中每个字节的编号（以十六进制表示）：<br><img src="https://s2.loli.net/2022/01/27/PFRL7A5QumTwapE.png" alt="4G 内存中每个字节的编号"></p><p>这内存中字节的编号称为地址（Address）或指针（Pointer）。地址从 0 开始依次增加。</p><p>对于 32 位环境，程序能够使用的内存为 <strong>4GB</strong>，最小的地址为 0，最大的地址为 0XFFFFFFFF。我们来验证一下为什么是4G。</p><p>下面是内存单位的一些进制转换：</p><figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs routeros">K是千 M是兆 G是吉咖 T是太拉<br><br>8bit(位)=1Byte(字节)<br><br>1024Byte(字节)=1KB<br><br><span class="hljs-attribute">1024KB</span>=1MB<br><br><span class="hljs-attribute">1024MB</span>=1GB<br><br><span class="hljs-attribute">1024GB</span>=1TB<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/01/27/rs7US1ktImpMDFc.png" alt="image-20210816214010338"> </p><p>可以看到16进制的FFFFFFFF转换为十进制为4294967295,再加上全0，一共是4294967296个字节</p><p>而4G  =  4*1024M  =  4*1024*1024K =4*1024*1024*1024byte（字节）=4294967296 byte (字节）刚好相等，所以说对于 32 位环境，程序能够使用的内存为 <strong>4GB</strong></p><p>下面的代码演示了如何输出一个地址：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-keyword">int</span> a = <span class="hljs-number">100</span>;<br>    <span class="hljs-keyword">char</span> str[<span class="hljs-number">20</span>] = <span class="hljs-string">&quot;c.biancheng.net&quot;</span>;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%#X, %#X\n&quot;</span>, &amp;a, str);<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>运行结果：<br>0X60FEEC, 0X60FED8</p><p><code>%#X</code>表示以十六进制形式输出，并附带前缀<code>0X</code>。a 是一个变量，用来存放整数，需要在前面加<code>&amp;</code>来获得它的地址；</p><p>str 本身就表示字符串的首地址，不需要加<code>&amp;</code>。</p><p>CPU 访问内存时需要的是地址，而不是变量名和函数名！变量名和函数名只是地址的一种助记符，当源文件被编译和链接成可执行程序后，它们都会被替换成地址。编译和链接过程的一项重要任务就是找到这些名称所对应的地址。</p><p>假设变量 a、b、c 在内存中的地址分别是 0X1000、0X2000、0X3000，那么加法运算<code>c = a + b;</code>将会被转换成类似下面的形式：</p><p>0X3000 = (0X1000) + (0X2000);</p><p><code>( )</code>表示取值操作，整个表达式的意思是，取出地址 0X1000 和 0X2000 上的值，将它们相加，把相加的结果赋值给地址为 0X3000 的内存</p><p>变量名和函数名为我们提供了方便，让我们在编写代码的过程中可以使用易于阅读和理解的英文字符串，不用直接面对二进制地址。</p><p>需要注意的是，虽然变量名、函数名、字符串名和数组名在本质上是一样的，它们都是地址的助记符。</p><h3 id="3-1-指针与指针变量"><a href="#3-1-指针与指针变量" class="headerlink" title="3.1 指针与指针变量"></a>3.1 指针与指针变量</h3><p>数据在内存中的地址也称为指针，如果一个变量存储了一份数据的指针，我们就称它为<strong>指针变量</strong>。</p><p>现在假设有一个 char 类型的变量 c，它存储了字符 ‘K’（ASCII码为十进制数 75），并占用了地址为 0X11A 的内存（地址通常用十六进制表示）。另外有一个指针变量 p，它的值为 0X11A，正好等于变量 c 的地址，这种情况我们就称 p 指向了 c，或者说 p 是指向变量 c 的指针。</p><p><img src="https://s2.loli.net/2022/01/27/1p769afZkQgw4in.png" alt="img"></p><h4 id="1-定义指针变量"><a href="#1-定义指针变量" class="headerlink" title="1.定义指针变量"></a>1.定义指针变量</h4><p>定义指针变量与定义普通变量非常类似，不过要在变量名前面加星号<code>*</code>，格式为：</p><figure class="highlight perl"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs perl"><span class="hljs-keyword">int</span> *p1;<span class="hljs-regexp">//</span><span class="hljs-string">`*`</span>表示这是一个指针变量，<span class="hljs-string">`int`</span>表示该指针变量所指向的数据的类型 为整型。<br></code></pre></td></tr></table></figure><p>p1 是一个指向 int 类型数据的指针变量，至于 p1 究竟指向哪一份数据，应该由赋予它的值决定。再如：</p><figure class="highlight abnf"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs abnf">int a = <span class="hljs-number">100</span><span class="hljs-comment">;int *p_a = &amp;a;</span><br></code></pre></td></tr></table></figure><p>在定义指针变量 p_a 的同时对它进行初始化，并将变量 a 的地址赋予它，此时 p_a 就指向了 a。值得注意的是，p_a 需要的一个地址，a 前面必须要加取地址符<code>&amp;</code>，否则是不对的。</p><p><code>*</code>是一个特殊符号，表明一个变量是指针变量，定义 p1、p2 时必须带<code>*</code>。而给 p1、p2 赋值时，因为已经知道了它是一个指针变量，就没必要多此一举再带上<code>*</code>，后边可以像使用普通变量一样来使用指针变量。也就是说，**定义指针变量时必须带<code>*</code>，给指针变量赋值时不能带<code>*</code>**。</p><p>假设变量 a、b、c、d 的地址分别为 0X1000、0X1004、0X2000、0X2004，下面的示意图很好地反映了 p1、p2 指向的变化：</p><p><img src="https://s2.loli.net/2022/01/27/fvRe6Ew4q9A5CYH.jpg" alt="img"></p><p>需要强调的是，**p1、p2 的类型分别是<code>float*</code>和<code>char*</code>**，而不是<code>float</code>和<code>char</code>，它们是完全不同的数据类型，要引起注意。</p><p>指针变量也可以连续定义，例如：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-keyword">int</span> *a, *b, *c;  <span class="hljs-comment">//a、b、c 的类型都是 int*</span><br></code></pre></td></tr></table></figure><p>注意每个变量前面都要带<code>*</code>。如果写成下面的形式，那么只有 a 是指针变量，b、c 都是类型为 int 的普通变量：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-keyword">int</span> *a, b, c;<br></code></pre></td></tr></table></figure><h4 id="2-通过指针变量取得数据"><a href="#2-通过指针变量取得数据" class="headerlink" title="2.通过指针变量取得数据"></a>2.通过指针变量取得数据</h4><p>指针变量存储了数据的地址，通过指针变量能够获得该地址上的数据，格式为：</p><p>*p;</p><p>这里的<code>*</code>称为指针运算符，用来取得某个地址上的数据，请看下面的例子：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-keyword">int</span> a = <span class="hljs-number">15</span>;<br>    <span class="hljs-keyword">int</span> *p = &amp;a;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%d, %d\n&quot;</span>, a, *p);  <span class="hljs-comment">//两种方式都可以输出a的值</span><br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>运行结果：<br>15, 15</p><p>假设 a 的地址是 0X1000，p 指向 a 后，p 本身的值也会变为 0X1000，<em>p 表示获取地址 0X1000 上的数据，也即变量 a 的值。从运行结果看，</em>p 和 a 是等价的。</p><p>虽然通过 *p 和 a 获取到的数据一样，但它们的运行过程稍有不同：a 只需要一次运算就能够取得数据，而 *p 要经过两次运算，多了一层“间接”。</p><p>假设变量 a、p 的地址分别为 0X1000、0XF0A0，它们的指向关系如下图所示：</p><p><img src="https://s2.loli.net/2022/01/27/68AtojJMnURqGuX.jpg" alt="img"></p><p>程序被编译和链接后，a、p 被替换成相应的地址。使用 *p 的话，要先通过地址 0XF0A0 取得变量 p 本身的值，这个值是变量 a 的地址，然后再通过这个值取得变量 a 的数据，前后共有两次运算；而使用 a 的话，可以通过地址 0X1000 直接取得它的数据，只需要一步运算。</p><p>指针除了可以获取内存上的数据，也可以修改内存上的数据，例如：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-keyword">int</span> a = <span class="hljs-number">15</span>, b = <span class="hljs-number">99</span>, c = <span class="hljs-number">222</span>;<br>    <span class="hljs-keyword">int</span> *p = &amp;a;  <span class="hljs-comment">//定义指针变量</span><br>    *p = b;  <span class="hljs-comment">//通过指针变量修改内存上的数据</span><br>    c = *p;  <span class="hljs-comment">//通过指针变量获取内存上的数据</span><br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%d, %d, %d, %d\n&quot;</span>, a, b, c, *p);<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>运行结果：<br>99, 99, 99, 99</p><p>*p 代表的是 a 中的数据，它等价于 a，可以将另外的一份数据赋值给它，也可以将它赋值给另外的一个变量。</p><p><code>*</code>在不同的场景下有不同的作用：<code>*</code>可以用在指针变量的定义中，表明这是一个指针变量，以和普通变量区分开；使用指针变量时在前面加<code>*</code>表示获取指针指向的数据，或者说表示的是指针指向的数据本身。</p><p>也就是说，定义指针变量时的<code>*</code>和使用指针变量时的<code>*</code>意义完全不同。以下面的语句为例：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-keyword">int</span> *p = &amp;a;*p = <span class="hljs-number">100</span>;<br></code></pre></td></tr></table></figure><p>第1行代码中<code>*</code>用来指明 p 是一个指针变量，第2行代码中<code>*</code>用来获取指针指向的数据。</p><p>【示例】通过指针交换两个变量的值。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-keyword">int</span> a = <span class="hljs-number">100</span>, b = <span class="hljs-number">999</span>, temp;<br>    <span class="hljs-keyword">int</span> *pa = &amp;a, *pb = &amp;b;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;a=%d, b=%d\n&quot;</span>, a, b);<br>    <span class="hljs-comment">/*****开始交换*****/</span><br>    temp = *pa;  <span class="hljs-comment">//将a的值先保存起来</span><br>    *pa = *pb;  <span class="hljs-comment">//将b的值交给a</span><br>    *pb = temp;  <span class="hljs-comment">//再将保存起来的a的值交给b</span><br>    <span class="hljs-comment">/*****结束交换*****/</span><br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;a=%d, b=%d\n&quot;</span>, a, b);<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>运行结果：<br>a=100, b=999<br>a=999, b=100</p><h4 id="3-关于-和-amp"><a href="#3-关于-和-amp" class="headerlink" title="3.关于 * 和 &amp;"></a>3.关于 * 和 &amp;</h4><p>已知有一个 int 类型的变量 a，pa 是指向它的指针.</p><p><strong><code>*&amp;a </code></strong>  可以理解为<code>*(&amp;a)</code>，<code>&amp;a</code>表示取变量 a 的地址（等价于 pa），<code>*(&amp;a)</code>表示取这个地址上的数据（等价于 *pa），绕来绕去，又回到了原点，<code>*&amp;a</code>仍然等价于 a。</p><p><strong><code>&amp;*pa</code></strong>  可以理解为<code>&amp;(*pa)</code>，<code>*pa</code>表示取得 pa 指向的数据（等价于 a），<code>&amp;(*pa)</code>表示数据的地址（等价于 &amp;a），所以<code>&amp;*pa</code>等价于 pa。</p><h5 id="对星号-的总结"><a href="#对星号-的总结" class="headerlink" title="对星号*的总结"></a>对星号<code>*</code>的总结</h5><ul><li>表示乘法，例如<code>int a = 3, b = 5, c;  c = a * b;</code></li><li>表示定义一个指针变量，以和普通变量区分开，例如<code>int a = 100;  int *p = &amp;a;</code>。</li><li>表示获取指针指向的数据，是一种间接操作，例如<code>int a, b, *p = &amp;a;  *p = 100;  b = *p;</code>。</li></ul><h3 id="3-2-指针变量续"><a href="#3-2-指针变量续" class="headerlink" title="3.2 指针变量续"></a>3.2 指针变量续</h3><p>编号（地址）：内存中每一个字节分配一个号码</p><p>定义一个变量 存放这个号码，这个变量就叫指针变量</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdlib.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span><br><span class="hljs-function"></span>&#123;<br>    <span class="hljs-keyword">int</span> num = <span class="hljs-number">100</span>;<br>    <span class="hljs-comment">//取变量的地址 用&amp;</span><br>    <span class="hljs-comment">//&amp;num 代表变量num的起始地址</span><br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%p\n&quot;</span>, &amp;num);<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%#X\n&quot;</span>, &amp;num);<br><br>    <span class="hljs-comment">//需求：定义一个指针变量，保存num的地址</span><br>    <span class="hljs-comment">//在定义的时候：*说明p是指针变量 而不是普通变量</span><br>    <span class="hljs-keyword">int</span> *p = <span class="hljs-literal">NULL</span>;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;sizeof(p) = %d\n&quot;</span>, <span class="hljs-keyword">sizeof</span>(p));<br>    <br>    <span class="hljs-comment">//num的地址 与 p建立关系</span><br>    p = &amp;num;<br>    <br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;num = %d\n&quot;</span>, num);<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;*p = %d\n&quot;</span>, *p);<span class="hljs-comment">//使用中：*p表示取p保存的地址编号 对应空间的内容</span><br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;p = %d\n&quot;</span>, p);<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;&amp;num = %d\n&quot;</span>, &amp;num);<br>    <br>&#125;<br></code></pre></td></tr></table></figure><img src="https://s2.loli.net/2022/01/27/bAuUwf2YmVnhD93.png" alt="image-20210808094827650" style="zoom: 67%;" /> <h4 id="指针变量两种类型"><a href="#指针变量两种类型" class="headerlink" title="指针变量两种类型"></a>指针变量两种类型</h4><p>1.自身的类型</p><p>2.指向的类型</p><p><strong>指针变量指向类型的作用</strong>：决定了指针变量所取空间内容的宽度，决定了指针变量+1所跳过的单位跨度</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdlib.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span><br><span class="hljs-function"></span>&#123;<br>    <span class="hljs-keyword">int</span> num = <span class="hljs-number">10</span>;<br>    <span class="hljs-keyword">int</span> *p = <span class="hljs-literal">NULL</span>;<br>    <span class="hljs-comment">//p自身的类型是 int *</span><br>    <span class="hljs-comment">//p指向的类型是 int</span><br>    p = &amp;num;<br>    <span class="hljs-comment">//指针变量指向类型的作用：决定了指针变量所取空间内容的宽度</span><br>    <span class="hljs-comment">//决定了指针变量+1所跳过的单位跨度</span><br><br>    <span class="hljs-comment">//指针变量的跨度</span><br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;&amp;num = %u\n&quot;</span>, &amp;num);<span class="hljs-comment">//%u 无符号10进制整数</span><br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;p = %u\n&quot;</span>, p);<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;p+1 = %u\n&quot;</span>, p+<span class="hljs-number">1</span>);<br><br>    <span class="hljs-keyword">char</span> *p1 = &amp;num;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;p1 = %u\n&quot;</span>, p1);<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;p1+1 = %u\n&quot;</span>, p1+<span class="hljs-number">1</span>);<br><br>    <span class="hljs-comment">//num的值</span><br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;*p = %d\n&quot;</span>, *p);<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;*p1 = %d\n&quot;</span>, *p1);<br>&#125;<br><br></code></pre></td></tr></table></figure><h4 id="指针变量的运算"><a href="#指针变量的运算" class="headerlink" title="指针变量的运算"></a>指针变量的运算</h4><p>指针变量保存的是地址，而地址本质上是一个整数，所以指针变量可以进行部分运算，运算，例如加法、减法、比较等。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-keyword">int</span>    a = <span class="hljs-number">10</span>,   *pa = &amp;a, *paa = &amp;a;<br>    <span class="hljs-keyword">double</span> b = <span class="hljs-number">99.9</span>, *pb = &amp;b;<br>    <span class="hljs-keyword">char</span>   c = <span class="hljs-string">&#x27;@&#x27;</span>,  *pc = &amp;c;<br>    <span class="hljs-comment">//最初的值</span><br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;&amp;a=%#X, &amp;b=%#X, &amp;c=%#X\n&quot;</span>, &amp;a, &amp;b, &amp;c);<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;pa=%#X, pb=%#X, pc=%#X\n&quot;</span>, pa, pb, pc);<br>    <span class="hljs-comment">//加法运算</span><br>    pa++; pb++; pc++;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;pa=%#X, pb=%#X, pc=%#X\n&quot;</span>, pa, pb, pc);<br>    <span class="hljs-comment">//减法运算</span><br>    pa -= <span class="hljs-number">2</span>; pb -= <span class="hljs-number">2</span>; pc -= <span class="hljs-number">2</span>;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;pa=%#X, pb=%#X, pc=%#X\n&quot;</span>, pa, pb, pc);<br>    <span class="hljs-comment">//比较运算</span><br>    <span class="hljs-keyword">if</span>(pa == paa)&#123;<br>        <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%d\n&quot;</span>, *paa);<br>    &#125;<span class="hljs-keyword">else</span>&#123;<br>        <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%d\n&quot;</span>, *pa);<br>    &#125;<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>运行结果：</p><figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs routeros">&amp;<span class="hljs-attribute">a</span>=0X61FEEC, &amp;<span class="hljs-attribute">b</span>=0X61FEE0, &amp;<span class="hljs-attribute">c</span>=0X61FEDF<br><span class="hljs-attribute">pa</span>=0X61FEEC, <span class="hljs-attribute">pb</span>=0X61FEE0, <span class="hljs-attribute">pc</span>=0X61FEDF<br><span class="hljs-attribute">pa</span>=0X61FEF0, <span class="hljs-attribute">pb</span>=0X61FEE8, <span class="hljs-attribute">pc</span>=0X61FEE0<br><span class="hljs-attribute">pa</span>=0X61FEE8, <span class="hljs-attribute">pb</span>=0X61FED8, <span class="hljs-attribute">pc</span>=0X61FEDE<br>6422400<br></code></pre></td></tr></table></figure><p>从运算结果可以看出：pa、pb、pc 每次加 1，它们的地址分别增加 4、8、1，正好是 int、double、char 类型的长度；减 2 时，地址分别减少 8、16、2，正好是 int、double、char 类型长度的 2 倍。</p><p><strong>指针变量加减运算的结果跟数据类型的长度有关，而不是简单地加 1 或减 1</strong></p><p>指针变量除了可以参与加减运算，还可以参与比较运算。当对指针变量进行比较运算时，比较的是指针变量本身的值，也就是数据的地址。如果地址相等，那么两个指针就指向同一份数据，否则就指向不同的数据。</p><p>上面的代码（第一个例子）在比较 pa 和 paa 的值时，pa 已经指向了 a 的上一份数据，所以它们不相等。而 a 的上一份数据又不知道是什么，所以会导致 printf() 输出一个没有意义的数。</p><p>另外需要说明的是，不能对指针变量进行乘法、除法、取余等其他运算，除了会发生语法错误，也没有实际的含义。</p><h4 id="指针变量深入"><a href="#指针变量深入" class="headerlink" title="指针变量深入"></a>指针变量深入</h4><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdlib.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span><br><span class="hljs-function"></span>&#123;<br>    <span class="hljs-keyword">int</span> num = <span class="hljs-number">0x18283848</span>;<br>    <span class="hljs-keyword">int</span> *p1 = &amp;num;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;*p1 = %#X\n&quot;</span>, *p1);<br><br>    <span class="hljs-keyword">short</span> *p2 = &amp;num;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;*p2 = %#X\n&quot;</span>, *p2);<br><br>    <span class="hljs-keyword">char</span> *p3 = &amp;num;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;*p3 = %#X\n&quot;</span>, *p3);<br><br>    <span class="hljs-comment">//如何得到1828</span><br>    <span class="hljs-keyword">short</span> *p4 = &amp;num;<br>    p4 = p4+<span class="hljs-number">1</span>;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;*p4 = %#X\n&quot;</span>, *p4);<br><br>    <span class="hljs-comment">//如何得到2838</span><br>    <span class="hljs-keyword">char</span> *p5 = &amp;num;<br>    p5 = p5++;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;*p5 = %#X\n&quot;</span>, *(<span class="hljs-keyword">short</span> *)p5);<span class="hljs-comment">//把p5指针转换为 short * 类型</span><br>    <br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/01/27/Zq2inlTRPchzj6S.png" alt="image-20210808103236950"> </p><h2 id="4-数组指针"><a href="#4-数组指针" class="headerlink" title="4. 数组指针"></a>4. 数组指针</h2><p>数组（Array）是一系列具有相同类型的数据的集合，每一份数据叫做一个数组元素（<strong>Element</strong>）。数组中的所有元素在内存中是连续排列的，整个数组占用的是一块内存。</p><p>以<code>int arr[] = &#123; 99, 15, 100, 888, 252 &#125;;</code>为例，该数组在内存中的分布如下图所示：</p><p><img src="https://s2.loli.net/2022/01/27/ijfO6TgV3LQUDyR.jpg" alt="img"></p><p>定义数组时，要给出数组名和数组长度，数组名可以认为是一个指针称为数组的<strong>首地址</strong>。以上面的数组为例，下图是 arr 的指向：</p><p><img src="https://s2.loli.net/2022/01/27/6yS4GktPWQflzdK.jpg" alt="img"></p><h3 id="1）-用指针方式遍历数组元素"><a href="#1）-用指针方式遍历数组元素" class="headerlink" title="1） 用指针方式遍历数组元素"></a>1） 用指针方式遍历数组元素</h3><p>下面的例子演示了如何以指针的方式遍历数组元素：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-keyword">int</span> arr[] = &#123; <span class="hljs-number">99</span>, <span class="hljs-number">15</span>, <span class="hljs-number">100</span>, <span class="hljs-number">888</span>, <span class="hljs-number">252</span> &#125;;<br>    <span class="hljs-keyword">int</span> len = <span class="hljs-keyword">sizeof</span>(arr) / <span class="hljs-keyword">sizeof</span>(<span class="hljs-keyword">int</span>);  <span class="hljs-comment">//求数组长度，整个数组所占用的字节数/一个数组元素所占用的字节数</span><br>    <span class="hljs-keyword">int</span> i;<br>    <span class="hljs-comment">/*数组名arr指向数组的第0个元素，表示数组首地址,arr+i第 i 个元素，*(arr+i) 取第i个元素的数据，等价于arr[i]*/</span><br>    <span class="hljs-keyword">for</span>(i=<span class="hljs-number">0</span>; i&lt;len; i++)&#123;<br>        <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%d  &quot;</span>, *(arr+i) );  <span class="hljs-comment">//*(arr+i)等价于arr[i]</span><br>    &#125;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;\n&quot;</span>);<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>运行结果：<br>99 15 100 888 252</p><h3 id="2）-用数组指针遍历数组元素"><a href="#2）-用数组指针遍历数组元素" class="headerlink" title="2） 用数组指针遍历数组元素"></a>2） 用数组指针遍历数组元素</h3><p>我们也可以定义一个指向数组的指针，例如：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-keyword">int</span> arr[] = &#123; <span class="hljs-number">99</span>, <span class="hljs-number">15</span>, <span class="hljs-number">100</span>, <span class="hljs-number">888</span>, <span class="hljs-number">252</span> &#125;;<br><span class="hljs-keyword">int</span> *p = arr; <span class="hljs-comment">//数组指针（一个指针指向了数组），p 指向的数组元素是 int 类型， p 的类型是int *</span><br></code></pre></td></tr></table></figure><p>arr 本身就是一个指针，可以直接赋值给指针变量 p。arr 是数组第 0 个元素的地址.</p><p>所以<code>int *p = arr;</code>也可以写作<code>int *p = &amp;arr[0];</code>。也就是说 <strong>arr、p、&amp;arr[0]</strong> 等价，它们都指向数组第 0 个元素，或者说指向数组的开头。</p><p><strong>数组指针指向的是数组中的一个具体元素，而不是整个数组</strong>，所以数组指针的类型和数组元素的类型有关</p><p>反过来想，p 并不知道它指向的是一个数组，p 只知道它指向的是一个整数，究竟如何使用 p 取决于程序员的编码。</p><p>更改上面的代码，使用<strong>数组指针</strong>来遍历数组元素：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-keyword">int</span> arr[] = &#123; <span class="hljs-number">99</span>, <span class="hljs-number">15</span>, <span class="hljs-number">100</span>, <span class="hljs-number">888</span>, <span class="hljs-number">252</span> &#125;;<br>    <span class="hljs-keyword">int</span> i, *p = arr, len = <span class="hljs-keyword">sizeof</span>(arr) / <span class="hljs-keyword">sizeof</span>(<span class="hljs-keyword">int</span>);<br>    <span class="hljs-keyword">for</span>(i=<span class="hljs-number">0</span>; i&lt;len; i++)&#123;<br>        <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%d  &quot;</span>, *(p+i) );<span class="hljs-comment">//指针变量的加法，用 * 获取地址上的数据</span><br>    &#125;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;\n&quot;</span>);<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p><strong>p 只是一个指向 int 类型的指针，编译器并不知道它指向的到底是一个整数还是一系列整数（数组）</strong></p><p>更改上面的代码，让 p 指向数组中的第二个元素：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-keyword">int</span> arr[] = &#123; <span class="hljs-number">99</span>, <span class="hljs-number">15</span>, <span class="hljs-number">100</span>, <span class="hljs-number">888</span>, <span class="hljs-number">252</span> &#125;;<br>    <span class="hljs-keyword">int</span> *p = &amp;arr[<span class="hljs-number">2</span>];  <span class="hljs-comment">//也可以写作 int *p = arr + 2;</span><br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%d, %d, %d, %d, %d\n&quot;</span>, *(p<span class="hljs-number">-2</span>), *(p<span class="hljs-number">-1</span>), *p, *(p+<span class="hljs-number">1</span>), *(p+<span class="hljs-number">2</span>) );<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>运行结果：<br>99, 15, 100, 888, 252</p><h3 id="3）-访问数组指针的两种方式"><a href="#3）-访问数组指针的两种方式" class="headerlink" title="3） 访问数组指针的两种方式"></a>3） 访问数组指针的两种方式</h3><p>引入数组指针后，我们就有两种方案来访问数组元素了，一种是使用下标，另外一种是使用指针。</p><p><strong>1) 使用下标</strong></p><p>也就是采用 <strong>arr[i]</strong> 的形式访问数组元素。如果 p 是指向数组 arr 的指针，那么也可以使用 <strong>p[i]</strong> 来访问数组元素，等价于 arr[i]。</p><p>比如下面的代码：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-keyword">int</span> arr[] = &#123; <span class="hljs-number">99</span>, <span class="hljs-number">15</span>, <span class="hljs-number">100</span>, <span class="hljs-number">888</span>, <span class="hljs-number">252</span> &#125;;<br>    <span class="hljs-keyword">int</span> i, *p = arr, len = <span class="hljs-keyword">sizeof</span>(arr) / <span class="hljs-keyword">sizeof</span>(<span class="hljs-keyword">int</span>);<br>    <span class="hljs-keyword">for</span>(i=<span class="hljs-number">0</span>; i&lt;len; i++)&#123;<br>        <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%d  &quot;</span>, p[i] );<span class="hljs-comment">//使用p[i]来访问数组元素,等价于 arr[i]</span><br>    &#125;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;\n&quot;</span>);<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p><strong>2) 使用指针</strong></p><p>也就是使用 *(p+i) 的形式访问数组元素。另外数组名本身也是指针，也可以使用 *(arr+i) 来访问数组元素，它等价于 *(p+i)。</p><p>不管是数组名还是数组指针，都可以使用上面的两种方式来访问数组元素。不同的是，数组名是常量，它的值不能改变，而数组指针是变量（除非特别指明它是常量），它的值可以任意改变。也就是说，数组名只能指向数组的开头，而数组指针可以先指向数组开头，再指向其他元素。</p><p>更改上面的代码，借助自增运算符来遍历数组元素：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-keyword">int</span> arr[] = &#123; <span class="hljs-number">99</span>, <span class="hljs-number">15</span>, <span class="hljs-number">100</span>, <span class="hljs-number">888</span>, <span class="hljs-number">252</span> &#125;;<br>    <span class="hljs-keyword">int</span> i, *p = arr, len = <span class="hljs-keyword">sizeof</span>(arr) / <span class="hljs-keyword">sizeof</span>(<span class="hljs-keyword">int</span>);<br>    <span class="hljs-keyword">for</span>(i=<span class="hljs-number">0</span>; i&lt;len; i++)&#123;<br>        <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%d  &quot;</span>, *p++);<span class="hljs-comment">//即 *(p++), 不能写成*arr++，因为arr是常量</span><br>    &#125;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;\n&quot;</span>);<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>运行结果：<br>99 15 100 888 252</p><h3 id="4）-关于数组指针的思考题"><a href="#4）-关于数组指针的思考题" class="headerlink" title="4） 关于数组指针的思考题"></a>4） 关于数组指针的思考题</h3><p>*<em>假设 p 是指向数组 arr 中第 n 个元素的指针，那么 <em>p++、</em>++p、(<em>p)++ 分别是什么意思呢？</em></em></p><p>*<strong>p++</strong> 等价于 *(p++)，表示先取得第 n 个元素的值，再将 p 指向下一个元素。</p><p>***++p** 等价于 *(++p)，会先进行 ++p 运算，使得 p 的值增加，指向下一个元素，整体上相当于 *(p+1)，所以会获得第 n+1 个数组元素的值。</p><p>**(<em>p)++</em>* 就非常简单了，会先取得第 n 个元素的值，再对该元素的值加 1。假设 p 指向第 0  个元素，并且第 0 个元素的值为 99，执行完该语句后，第 0  个元素的值就会变为 100。</p><h2 id="5-字符串指针"><a href="#5-字符串指针" class="headerlink" title="5. 字符串指针"></a>5. 字符串指针</h2><p>下面是字符数组的例子：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;string.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-keyword">char</span> str[] = <span class="hljs-string">&quot;beijingren&quot;</span>;<br>    <span class="hljs-keyword">int</span> len = <span class="hljs-built_in">strlen</span>(str), i;<br>    <span class="hljs-comment">//直接输出字符串</span><br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%s\n&quot;</span>, str);<br>    <span class="hljs-comment">//每次输出一个字符</span><br>    <span class="hljs-keyword">for</span>(i=<span class="hljs-number">0</span>; i&lt;len; i++)&#123;<br>        <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%c &quot;</span>, str[i]);<br>    &#125;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;\n&quot;</span>);<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>运行结果：</p><p>beijingren<br>b e i j i n g r e n</p><p>用<strong>指针</strong>的方式来输出字符串：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;string.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-keyword">char</span> str[] = <span class="hljs-string">&quot;biancheng&quot;</span>;<br>    <span class="hljs-keyword">char</span> *pstr = str;<br>    <span class="hljs-keyword">int</span> len = <span class="hljs-built_in">strlen</span>(str), i;<br>    <span class="hljs-comment">//使用*(pstr+i)</span><br>    <span class="hljs-keyword">for</span>(i=<span class="hljs-number">0</span>; i&lt;len; i++)&#123;<br>        <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%c&quot;</span>, *(pstr+i));<br>    &#125;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;\n&quot;</span>);<br>    <br>    <span class="hljs-comment">//使用pstr[i]</span><br>    <span class="hljs-keyword">for</span>(i=<span class="hljs-number">0</span>; i&lt;len; i++)&#123;<br>        <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%c&quot;</span>, pstr[i]);<br>    &#125;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;\n&quot;</span>);<br>    <br>    <span class="hljs-comment">//使用*(str+i)</span><br>    <span class="hljs-keyword">for</span>(i=<span class="hljs-number">0</span>; i&lt;len; i++)&#123;<br>        <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%c&quot;</span>, *(str+i));<br>    &#125;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;\n&quot;</span>);<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>运行结果：</p><p>biancheng<br>biancheng<br>biancheng</p><h2 id="6-指针变量作为函数参数"><a href="#6-指针变量作为函数参数" class="headerlink" title="6. 指针变量作为函数参数"></a>6. 指针变量作为函数参数</h2><p>交换两个变量的值：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">swap</span><span class="hljs-params">(<span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b)</span></span>&#123;<br>    <span class="hljs-keyword">int</span> temp;  <span class="hljs-comment">//临时变量</span><br>    temp = a;<br>    a = b;<br>    b = temp;<br>&#125;<br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-keyword">int</span> a = <span class="hljs-number">66</span>, b = <span class="hljs-number">99</span>;<br>    swap(a, b);<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;a = %d, b = %d\n&quot;</span>, a, b);<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>运行结果：</p><p>a = 66, b = 99</p><p>从结果可以看出，a、b 的值并没有发生改变，交换失败。这是因为 swap() 函数内部的 a、b 和 main() 函数内部的 a、b 是不同的变量，占用不同的内存，它们除了名字一样，没有其他任何关系，swap() 交换的是它内部 a、b 的值，不会影响它外部（main() 内部） a、b 的值。</p><p>改用指针变量作参数后就很容易解决上面的问题：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">swap</span><span class="hljs-params">(<span class="hljs-keyword">int</span> *p1, <span class="hljs-keyword">int</span> *p2)</span></span>&#123;<br>    <span class="hljs-keyword">int</span> temp;  <span class="hljs-comment">//临时变量</span><br>    temp = *p1;<br>    *p1 = *p2;<br>    *p2 = temp;<br>&#125;<br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-keyword">int</span> a = <span class="hljs-number">66</span>, b = <span class="hljs-number">99</span>;<br>    swap(&amp;a, &amp;b);<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;a = %d, b = %d\n&quot;</span>, a, b);<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>运行结果：<br>a = 99, b = 66</p><p>调用 swap() 函数时，将变量 a、b 的地址分别赋值给 p1、p2，这样 <em>p1、</em>p2 代表的就是变量 a、b 本身，交换 <em>p1、</em>p2 的值也就是交换 a、b 的值。函数运行结束后虽然会将 p1、p2 销毁，但它对外部 a、b 造成的影响是“持久化”的，不会随着函数的结束而“恢复原样”。</p><p>需要注意的是临时变量 temp，它的作用特别重要，因为执行<code>*p1 = *p2;</code>语句后 a 的值会被 b 的值覆盖，如果不先将 a 的值保存起来以后就找不到了。</p><p>当然我们也可以使用C++的引用 &amp; ，来实现同样的效果，而且更简单一点：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">swap</span><span class="hljs-params">(<span class="hljs-keyword">int</span> &amp;a, <span class="hljs-keyword">int</span> &amp;b)</span></span>&#123;<span class="hljs-comment">//对参数的修改“带回来”</span><br>    <span class="hljs-keyword">int</span> temp;  <span class="hljs-comment">//临时变量</span><br>    temp = a;<br>    a = b;<br>    b = temp;<br>&#125;<br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-keyword">int</span> a = <span class="hljs-number">66</span>, b = <span class="hljs-number">99</span>;<br>    <span class="hljs-built_in">swap</span>(a, b);<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;a = %d, b = %d\n&quot;</span>, a, b);<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>运行结果为：a = 99, b = 66</p><p>&amp; 在C语言中是取地址符，这里指C++的引用，注意上面这段代码要在C++程序中才能运行，也就是.cpp文件</p><h2 id="7-用数组作为函数参数"><a href="#7-用数组作为函数参数" class="headerlink" title="7. 用数组作为函数参数"></a>7. 用数组作为函数参数</h2><p>数组是一系列数据的集合，无法通过参数将它们一次性传递到函数内部，如果希望在函数内部操作数组，必须传递数组指针。下面的例子定义了一个函数 max()，用来查找数组中值最大的元素：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">max</span><span class="hljs-params">(<span class="hljs-keyword">int</span> *intArr, <span class="hljs-keyword">int</span> len)</span></span>&#123;<br>    <span class="hljs-keyword">int</span> i, maxValue = intArr[<span class="hljs-number">0</span>];  <span class="hljs-comment">//假设第0个元素是最大值</span><br>    <span class="hljs-keyword">for</span>(i=<span class="hljs-number">1</span>; i&lt;len; i++)&#123;<br>        <span class="hljs-keyword">if</span>(maxValue &lt; intArr[i])&#123;<br>            maxValue = intArr[i];<br>        &#125;<br>    &#125;<br><br>    <span class="hljs-keyword">return</span> maxValue;<br>&#125;<br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-keyword">int</span> nums[<span class="hljs-number">6</span>], i, maxval;<br>    <span class="hljs-keyword">int</span> len = <span class="hljs-keyword">sizeof</span>(nums)/<span class="hljs-keyword">sizeof</span>(<span class="hljs-keyword">int</span>);<br>    <span class="hljs-comment">//读取用户输入的数据并赋值给数组元素</span><br>    <span class="hljs-keyword">for</span>(i=<span class="hljs-number">0</span>; i&lt;len; i++)&#123;<br>        <span class="hljs-built_in">scanf</span>(<span class="hljs-string">&quot;%d&quot;</span>, nums+i);<br>    &#125;<br>    maxval = max(nums, len);<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;Max value is %d!\n&quot;</span>, maxval);<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br><br></code></pre></td></tr></table></figure><p>运行结果：<br>输入6个元素：12 55 30 8 93 27<br>Max value is 93!</p><p>参数 intArr 仅仅是一个<strong>数组指针</strong>，在函数内部无法通过这个指针获得数组长度，必须将数组长度作为函数参数传递到函数内部。</p><p>数组 nums 的每个元素都是整数，scanf() 在读取用户输入的整数时，要求给出存储它的内存的地址，<code>nums+i</code>就是第 i 个数组元素的地址。</p><h2 id="8-指针作为函数的返回值"><a href="#8-指针作为函数的返回值" class="headerlink" title="8. 指针作为函数的返回值"></a>8. 指针作为函数的返回值</h2><p>C语言允许函数的返回值是一个<a href="http://c.biancheng.net/c/80/">指针</a>（地址），我们将这样的函数称为指针函数。下面的例子定义了一个函数 strlong()，用来返回两个字符串中较长的一个：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;string.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">char</span> *<span class="hljs-title">strlong</span><span class="hljs-params">(<span class="hljs-keyword">char</span> *str1, <span class="hljs-keyword">char</span> *str2)</span></span>&#123;<span class="hljs-comment">//用指针作为函数的返回值</span><br>    <span class="hljs-keyword">if</span>(<span class="hljs-built_in">strlen</span>(str1) &gt;= <span class="hljs-built_in">strlen</span>(str2))&#123;<br>        <span class="hljs-keyword">return</span> str1;<br>    &#125;<span class="hljs-keyword">else</span>&#123;<br>        <span class="hljs-keyword">return</span> str2;<br>    &#125;<br>&#125;<br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-keyword">char</span> str1[<span class="hljs-number">30</span>], str2[<span class="hljs-number">30</span>], *str;<br>    gets(str1);<br>    gets(str2);<br>    str = strlong(str1, str2);<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;Longer string: %s\n&quot;</span>, str);<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><h2 id="9-函数指针"><a href="#9-函数指针" class="headerlink" title="9. 函数指针"></a>9. 函数指针</h2><p>一个函数总是占用一段连续的内存区域，函数名在表达式中有时也会被转换为该函数所在内存区域的首地址，这和数组名非常类似。我们可以把函数的这个首地址（或称入口地址）赋予一个指针变量，使指针变量指向函数所在的内存区域，然后通过指针变量就可以找到并调用该函数。这种指针就是函数指针。</p><p><strong>函数指针的定义</strong>形式为：</p><p>**returnType (*pointerName)(param list)**;</p><p>returnType 为函数返回值类型，pointerName 为指针名称，param list 为函数参数列表。参数列表中可以同时给出参数的类型和名称，也可以只给出参数的类型，省略参数的名称，这一点和函数原型非常类似。</p><p>注意<code>( )</code>的优先级高于<code>*</code>，第一个括号不能省略，如果写作<code>returnType *pointerName(param list);</code>就成了函数原型，它表明函数的返回值类型为<code>returnType *</code>。</p><p>【实例】用指针来实现对函数的调用。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-comment">//返回两个数中较大的一个</span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">max</span><span class="hljs-params">(<span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b)</span></span>&#123;<br>    <span class="hljs-keyword">return</span> a &gt; b ? a : b;<span class="hljs-comment">//三目运算符</span><br>&#125;<br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-keyword">int</span> x, y, maxval;<br>    <span class="hljs-comment">//定义函数指针</span><br>    <span class="hljs-keyword">int</span> (*pmax)(<span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b) = max;  <span class="hljs-comment">//也可以写作int (*pmax)(int, int)</span><br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;Input two numbers:&quot;</span>);<br>    <span class="hljs-built_in">scanf</span>(<span class="hljs-string">&quot;%d %d&quot;</span>, &amp;x, &amp;y);<br>    maxval = (*pmax)(x, y);<span class="hljs-comment">//第14行</span><br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;Max value: %d\n&quot;</span>, maxval);<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>运行结果：<br>Input two numbers:10 50<br>Max value: 50</p><p>第 14 行代码对函数进行了调用。pmax 是一个函数指针，在前面加 * 就表示对它指向的函数进行调用。注意<code>( )</code>的优先级高于<code>*</code>，第一个括号不能省略。</p><h2 id="10-对C语言指针的总结"><a href="#10-对C语言指针的总结" class="headerlink" title="10. 对C语言指针的总结:"></a>10. 对C语言指针的总结:</h2><p>指针（Pointer）就是内存的地址，C语言允许用一个变量来存放指针，这种变量称为指针变量。指针变量可以存放基本类型数据的地址，也可以存放数组、函数以及其他指针变量的地址。</p><p>程序在运行过程中需要的是数据和指令的地址，变量名、函数名、字符串名和数组名在本质上是一样的，它们都是地址的助记符：在编写代码的过程中，我们认为函数名、字符串名和数组名表示的是代码块或数据块的首地址；程序被编译和链接后，这些名字都会消失，取而代之的是它们对应的地址。</p><p>在我们目前所学到的语法中，星号<code>*</code>主要有三种用途：</p><ul><li>表示乘法，例如<code>int a = 3, b = 5, c;  c = a * b;</code>，这是最容易理解的。</li><li>表示定义一个指针变量，以和普通变量区分开，例如<code>int a = 100;  int *p = &amp;a;</code>。</li><li>表示获取指针指向的数据，是一种间接操作，例如<code>int a, b, *p = &amp;a;  *p = 100;  b = *p;</code></li></ul><ol><li><p>指针变量可以进行<strong>加减运算</strong>，例如<code>p++</code>、<code>p+i</code>、<code>p-=i</code>。指针变量的加减运算并不是简单的加上或减去一个整数，而是跟指针指向的<strong>数据类型有关</strong>。</p></li><li><p>给指针变量赋值时，要将一份数据的<strong>地址</strong>赋给它，不能直接赋给一个整数，例如<code>int *p = 1000;</code>是没有意义的，使用过程中一般会导致程序崩溃。</p></li><li><p>使用指针变量之前一定要<strong>初始化</strong>，否则就不能确定指针指向哪里，如果它指向的内存没有使用权限，程序就崩溃了。对于暂时没有指向的指针，<strong>建议赋值</strong><code>NULL</code>。</p></li><li><p>两个指针变量可以相减。如果两个指针变量指向同一个数组中的某个元素，那么相减的结果就是两个指针之间相差的元素个数。</p></li><li><p>数组也是有类型的，数组名的本意是表示一组类型相同的数据。在定义数组时，或者和 sizeof、&amp; 运算符一起使用时数组名才表示整个数组，表达式中的<strong>数组名会被转换为一个指向数组的指针</strong>。</p></li></ol><h1 id="四、结构体"><a href="#四、结构体" class="headerlink" title="四、结构体"></a>四、结构体</h1><h2 id="1-C语言结构体"><a href="#1-C语言结构体" class="headerlink" title="1. C语言结构体"></a>1. C语言结构体</h2><p>C语言结构体（Struct）从本质上讲是一种自定义的数据类型，只不过这种数据类型比较复杂，是由 int、char、float 等基本类型组成的。你可以认为结构体是一种聚合类型。</p><p>在实际开发中，我们可以将一组类型不同的、但是用来描述同一件事物的变量放到结构体中。例如，在校学生有姓名、年龄、身高、成绩等属性，学了结构体后，我们就不需要再定义多个变量了，将它们都放到结构体中即可。</p><p>在C语言中，可以使用<strong>结构体（Struct）</strong>来存放一组不同类型的数据。结构体的定义形式为：</p><p>struct 结构体名{<br>  结构体所包含的变量或数组<br>};</p><p>结构体是一种集合，它里面包含了多个变量或数组，它们的类型可以相同，也可以不同，每个这样的变量或数组都称为结构体的成员（Member）。请看下面的一个例子：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">stu</span>&#123;</span><br>    <span class="hljs-keyword">char</span> *name;  <span class="hljs-comment">//姓名</span><br>    <span class="hljs-keyword">int</span> num;  <span class="hljs-comment">//学号</span><br>    <span class="hljs-keyword">int</span> age;  <span class="hljs-comment">//年龄</span><br>    <span class="hljs-keyword">char</span> group;  <span class="hljs-comment">//所在学习小组</span><br>    <span class="hljs-keyword">float</span> score;  <span class="hljs-comment">//成绩</span><br>&#125;;<br></code></pre></td></tr></table></figure><p>stu 为结构体名，它包含了 5 个成员，分别是 name、num、age、group、score。结构体成员的定义方式与变量和数组的定义方式相同，只是不能初始化。</p><blockquote><p>注意大括号后面的分号<code>;</code>不能少，这是一条完整的语句。</p></blockquote><p>结构体也是一种数据类型，它由程序员自己定义，可以包含多个其他类型的数据。</p><p>像 int、float、char 等是由C语言本身提供的数据类型，不能再进行分拆，我们称之为基本数据类型；而结构体可以包含多个基本类型的数据，也可以包含其他的结构体，我们将它称为复杂数据类型或构造数据类型。</p><h2 id="2-结构体变量"><a href="#2-结构体变量" class="headerlink" title="2. 结构体变量"></a>2. 结构体变量</h2><p>既然结构体是一种数据类型，那么就可以用它来定义变量。例如：</p><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-attribute">struct</span> stu stu<span class="hljs-number">1</span>, stu<span class="hljs-number">2</span>;<br></code></pre></td></tr></table></figure><p>定义了两个变量 stu1 和 stu2，它们都是 stu 类型，都由 5 个成员组成。注意关键字<code>struct</code>不能少。</p><p>stu 就像一个“模板”，定义出来的变量都具有相同的性质。也可以将结构体比作“图纸”，将结构体变量比作“零件”，根据同一张图纸生产出来的零件的特性都是一样的。</p><p>你也可以在定义结构体的同时定义结构体变量：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">stu</span>&#123;</span><br>    <span class="hljs-keyword">char</span> *name;  <span class="hljs-comment">//姓名</span><br>    <span class="hljs-keyword">int</span> num;  <span class="hljs-comment">//学号</span><br>    <span class="hljs-keyword">int</span> age;  <span class="hljs-comment">//年龄</span><br>    <span class="hljs-keyword">char</span> group;  <span class="hljs-comment">//所在学习小组</span><br>    <span class="hljs-keyword">float</span> score;  <span class="hljs-comment">//成绩</span><br>&#125; stu1, stu2;<br></code></pre></td></tr></table></figure><p>将变量放在结构体定义的最后即可。</p><p>如果只需要 stu1、stu2 两个变量，后面不需要再使用结构体名定义其他变量，那么在定义时也可以不给出结构体名，如下所示：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-class"><span class="hljs-keyword">struct</span>&#123;</span>  <span class="hljs-comment">//没有写 stu</span><br>    <span class="hljs-keyword">char</span> *name;  <span class="hljs-comment">//姓名</span><br>    <span class="hljs-keyword">int</span> num;  <span class="hljs-comment">//学号</span><br>    <span class="hljs-keyword">int</span> age;  <span class="hljs-comment">//年龄</span><br>    <span class="hljs-keyword">char</span> group;  <span class="hljs-comment">//所在学习小组</span><br>    <span class="hljs-keyword">float</span> score;  <span class="hljs-comment">//成绩</span><br>&#125; stu1, stu2;<br></code></pre></td></tr></table></figure><p>这样做书写简单，但是因为没有结构体名，后面就没法用该结构体定义新的变量。</p><p>理论上讲结构体的各个成员在内存中是连续存储的，和数组非常类似，例如上面的结构体变量 stu1、stu2 的内存分布如下图所示，共占用 4+4+4+1+4 = 17 个字节。</p><p><img src="https://s2.loli.net/2022/01/27/OwHf2aYWNdvsDAX.jpg" alt="img"></p><p>但是在编译器的具体实现中，各个成员之间可能会存在缝隙，对于 stu1、stu2，成员变量 group 和 score 之间就存在 3 个字节的空白填充（见下图）。这样算来，stu1、stu2 其实占用了 17 + 3 = 20 个字节。</p><p><img src="https://s2.loli.net/2022/01/27/wpgbDIemTCq7ns1.jpg" alt="img"></p><h2 id="3-成员的获取和赋值"><a href="#3-成员的获取和赋值" class="headerlink" title="3. 成员的获取和赋值"></a>3. 成员的获取和赋值</h2><p>结构体和数组类似，也是一组数据的集合，整体使用没有太大的意义。数组使用下标<code>[ ]</code>获取单个元素，结构体使用点号<code>.</code>获取单个成员。获取结构体成员的一般格式为：</p><p>结构体变量名.成员名;</p><p>通过这种方式可以获取成员的值，也可以给成员赋值：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-class"><span class="hljs-keyword">struct</span>&#123;</span><br>        <span class="hljs-keyword">char</span> *name;  <span class="hljs-comment">//姓名</span><br>        <span class="hljs-keyword">int</span> num;  <span class="hljs-comment">//学号</span><br>        <span class="hljs-keyword">int</span> age;  <span class="hljs-comment">//年龄</span><br>        <span class="hljs-keyword">char</span> group;  <span class="hljs-comment">//所在小组</span><br>        <span class="hljs-keyword">float</span> score;  <span class="hljs-comment">//成绩</span><br>    &#125; stu1;<br>    <span class="hljs-comment">//给结构体成员赋值</span><br>    stu1.name = <span class="hljs-string">&quot;Tom&quot;</span>;<br>    stu1.num = <span class="hljs-number">12</span>;<br>    stu1.age = <span class="hljs-number">18</span>;<br>    stu1.group = <span class="hljs-string">&#x27;A&#x27;</span>;<br>    stu1.score = <span class="hljs-number">136.5</span>;<br>    <span class="hljs-comment">//读取结构体成员的值</span><br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%s的学号是%d，年龄是%d，在%c组，今年的成绩是%.1f！\n&quot;</span>, stu1.name, stu1.num, stu1.age, stu1.group, stu1.score);<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>运行结果：<br>Tom的学号是12，年龄是18，在A组，今年的成绩是136.5！</p><p>除了可以对成员进行逐一赋值，也可以在定义时整体赋值，例如：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-class"><span class="hljs-keyword">struct</span>&#123;</span><br>    <span class="hljs-keyword">char</span> *name;  <span class="hljs-comment">//姓名</span><br>    <span class="hljs-keyword">int</span> num;  <span class="hljs-comment">//学号</span><br>    <span class="hljs-keyword">int</span> age;  <span class="hljs-comment">//年龄</span><br>    <span class="hljs-keyword">char</span> group;  <span class="hljs-comment">//所在小组</span><br>    <span class="hljs-keyword">float</span> score;  <span class="hljs-comment">//成绩</span><br>&#125; stu1, stu2 = &#123; <span class="hljs-string">&quot;Tom&quot;</span>, <span class="hljs-number">12</span>, <span class="hljs-number">18</span>, <span class="hljs-string">&#x27;A&#x27;</span>, <span class="hljs-number">136.5</span> &#125;;<br></code></pre></td></tr></table></figure><p>不过整体赋值仅限于定义结构体变量的时候，在使用过程中只能对成员逐一赋值，这和数组的赋值非常类似。</p><p><strong>需要注意的是，结构体是一种自定义的数据类型，是创建变量的模板，不占用内存空间；</strong></p><p><strong>结构体变量才包含了实实在在的数据，需要内存空间来存储。</strong></p><h2 id="4-结构体指针（指向结构体的指针）"><a href="#4-结构体指针（指向结构体的指针）" class="headerlink" title="4.结构体指针（指向结构体的指针）"></a>4.结构体指针（指向结构体的指针）</h2><h3 id="4-1-结构体指针"><a href="#4-1-结构体指针" class="headerlink" title="4.1 结构体指针"></a>4.1 结构体指针</h3><p>当一个指针变量指向结构体时，我们就称它为结构体指针，C语言结构体指针的定义形式一般为：</p><p>struct 结构体名 *变量名;</p><p>定义结构体指针的实例：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-comment">//结构体</span><br><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">stu</span>&#123;</span><br>    <span class="hljs-keyword">char</span> *name;  <span class="hljs-comment">//姓名</span><br>    <span class="hljs-keyword">int</span> num;  <span class="hljs-comment">//学号</span><br>    <span class="hljs-keyword">int</span> age;  <span class="hljs-comment">//年龄</span><br>    <span class="hljs-keyword">char</span> group;  <span class="hljs-comment">//所在小组</span><br>    <span class="hljs-keyword">float</span> score;  <span class="hljs-comment">//成绩</span><br>&#125; stu1 = &#123; <span class="hljs-string">&quot;Tom&quot;</span>, <span class="hljs-number">12</span>, <span class="hljs-number">18</span>, <span class="hljs-string">&#x27;A&#x27;</span>, <span class="hljs-number">136.5</span> &#125;;<br><br><span class="hljs-comment">//结构体指针</span><br><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">stu</span> *<span class="hljs-title">pstu</span> =</span> &amp;stu1;<br></code></pre></td></tr></table></figure><p>也可以在定义结构体的同时定义结构体指针：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">stu</span>&#123;</span><br>    <span class="hljs-keyword">char</span> *name;  <span class="hljs-comment">//姓名</span><br>    <span class="hljs-keyword">int</span> num;  <span class="hljs-comment">//学号</span><br>    <span class="hljs-keyword">int</span> age;  <span class="hljs-comment">//年龄</span><br>    <span class="hljs-keyword">char</span> group;  <span class="hljs-comment">//所在小组</span><br>    <span class="hljs-keyword">float</span> score;  <span class="hljs-comment">//成绩</span><br>&#125; stu1 = &#123; <span class="hljs-string">&quot;Tom&quot;</span>, <span class="hljs-number">12</span>, <span class="hljs-number">18</span>, <span class="hljs-string">&#x27;A&#x27;</span>, <span class="hljs-number">136.5</span> &#125;, *pstu = &amp;stu1;<br></code></pre></td></tr></table></figure><p>注意，结构体变量名和数组名不同，<strong>数组名</strong>在表达式中<strong>会被转换为数组指针</strong>，而<strong>结构体变量名不会转换为指针</strong>，无论在任何表达式中它表示的都是整个集合本身，要想取得结构体变量的地址，必须在前面加<code>&amp;</code>，所以给 pstu 赋值只能写作：</p><p>struct stu *pstu = &stu1;</p><p>而不能写作：</p><p>struct stu *pstu = stu1;</p><p>还应该注意，结构体和结构体变量是两个不同的概念：结构体是一种数据类型，是一种创建变量的模板，编译器不会为它分配内存空间，就像 int、float、char 这些关键字本身不占用内存一样；<strong>结构体变量才包含实实在在的数据</strong>，才需要内存来存储。下面的写法是错误的，不可能去取一个结构体名的地址，也不能将它赋值给其他变量：</p><p>struct stu *pstu = &stu;<br>struct stu *pstu = stu;</p><h3 id="4-2-获取结构体成员"><a href="#4-2-获取结构体成员" class="headerlink" title="4.2 获取结构体成员"></a>4.2 获取结构体成员</h3><p>通过结构体指针可以获取结构体成员，一般形式为：</p><p>(*pointer).memberName</p><p>或者：</p><p><strong>pointer-&gt;memberName</strong></p><p>第一种写法中，<code>.</code>的优先级高于<code>*</code>，<code>(*pointer)</code>两边的括号不能少。如果去掉括号写作<code>*pointer.memberName</code>，那么就等效于<code>*(pointer.memberName)</code>，这样意义就完全不对了。</p><p>第二种写法中，**<code>-&gt;</code>是一个新的运算符，习惯称它为“箭头”**，有了它，可以通过结构体指针直接取得结构体成员；</p><p>这也是**<code>-&gt;</code>在C语言中的唯一用途**。</p><p>上面的两种写法是等效的，我们通常采用后面的写法，这样更加直观。</p><p>【示例】结构体指针的使用。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-class"><span class="hljs-keyword">struct</span>&#123;</span><br>        <span class="hljs-keyword">char</span> *name;  <span class="hljs-comment">//姓名</span><br>        <span class="hljs-keyword">int</span> num;  <span class="hljs-comment">//学号</span><br>        <span class="hljs-keyword">int</span> age;  <span class="hljs-comment">//年龄</span><br>        <span class="hljs-keyword">char</span> group;  <span class="hljs-comment">//所在小组</span><br>        <span class="hljs-keyword">float</span> score;  <span class="hljs-comment">//成绩</span><br>    &#125; stu1 = &#123; <span class="hljs-string">&quot;Tom&quot;</span>, <span class="hljs-number">12</span>, <span class="hljs-number">18</span>, <span class="hljs-string">&#x27;A&#x27;</span>, <span class="hljs-number">136.5</span> &#125;, *pstu = &amp;stu1;<br>    <br>    <span class="hljs-comment">//读取结构体成员的值</span><br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%s的学号是%d，年龄是%d，在%c组，今年的成绩是%.1f！\n&quot;</span>, (*pstu).name, (*pstu).num, (*pstu).age, (*pstu).group, (*pstu).score);<br>    <br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%s的学号是%d，年龄是%d，在%c组，今年的成绩是%.1f！\n&quot;</span>, pstu-&gt;name, pstu-&gt;num, pstu-&gt;age, pstu-&gt;group, pstu-&gt;score);<br>    <br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>运行结果：<br>Tom的学号是12，年龄是18，在A组，今年的成绩是136.5！<br>Tom的学号是12，年龄是18，在A组，今年的成绩是136.5！</p><p>【示例】结构体数组指针的使用。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">stu</span>&#123;</span><br>    <span class="hljs-keyword">char</span> *name;  <span class="hljs-comment">//姓名</span><br>    <span class="hljs-keyword">int</span> num;  <span class="hljs-comment">//学号</span><br>    <span class="hljs-keyword">int</span> age;  <span class="hljs-comment">//年龄</span><br>    <span class="hljs-keyword">char</span> group;  <span class="hljs-comment">//所在小组</span><br>    <span class="hljs-keyword">float</span> score;  <span class="hljs-comment">//成绩</span><br>&#125;stus[] = &#123;<br>    &#123;<span class="hljs-string">&quot;Zhou ping&quot;</span>, <span class="hljs-number">5</span>, <span class="hljs-number">18</span>, <span class="hljs-string">&#x27;C&#x27;</span>, <span class="hljs-number">145.0</span>&#125;,<br>    &#123;<span class="hljs-string">&quot;Zhang ping&quot;</span>, <span class="hljs-number">4</span>, <span class="hljs-number">19</span>, <span class="hljs-string">&#x27;A&#x27;</span>, <span class="hljs-number">130.5</span>&#125;,<br>    &#123;<span class="hljs-string">&quot;Liu fang&quot;</span>, <span class="hljs-number">1</span>, <span class="hljs-number">18</span>, <span class="hljs-string">&#x27;A&#x27;</span>, <span class="hljs-number">148.5</span>&#125;,<br>    &#123;<span class="hljs-string">&quot;Cheng ling&quot;</span>, <span class="hljs-number">2</span>, <span class="hljs-number">17</span>, <span class="hljs-string">&#x27;F&#x27;</span>, <span class="hljs-number">139.0</span>&#125;,<br>    &#123;<span class="hljs-string">&quot;Wang ming&quot;</span>, <span class="hljs-number">3</span>, <span class="hljs-number">17</span>, <span class="hljs-string">&#x27;B&#x27;</span>, <span class="hljs-number">144.5</span>&#125;<br>&#125;, *ps;<br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-comment">//求数组长度</span><br>    <span class="hljs-keyword">int</span> len = <span class="hljs-keyword">sizeof</span>(stus) / <span class="hljs-keyword">sizeof</span>(struct stu);<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;Name\t\tNum\tAge\tGroup\tScore\t\n&quot;</span>);<br>    <span class="hljs-keyword">for</span>(ps=stus; ps&lt;stus+len; ps++)&#123;<br>        <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;%s\t%d\t%d\t%c\t%.1f\n&quot;</span>, ps-&gt;name, ps-&gt;num, ps-&gt;age, ps-&gt;group, ps-&gt;score);<br>    &#125;<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>运行结果：</p><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-attribute">Name</span>            Num     Age     Group   Score<br><span class="hljs-attribute">Zhou</span> ping       <span class="hljs-number">5</span>       <span class="hljs-number">18</span>      C       <span class="hljs-number">145</span>.<span class="hljs-number">0</span><br><span class="hljs-attribute">Zhang</span> ping      <span class="hljs-number">4</span>       <span class="hljs-number">19</span>      A       <span class="hljs-number">130</span>.<span class="hljs-number">5</span><br><span class="hljs-attribute">Liu</span> fang        <span class="hljs-number">1</span>       <span class="hljs-number">18</span>      A       <span class="hljs-number">148</span>.<span class="hljs-number">5</span><br><span class="hljs-attribute">Cheng</span> ling      <span class="hljs-number">2</span>       <span class="hljs-number">17</span>      F       <span class="hljs-number">139</span>.<span class="hljs-number">0</span><br><span class="hljs-attribute">Wang</span> ming       <span class="hljs-number">3</span>       <span class="hljs-number">17</span>      B       <span class="hljs-number">144</span>.<span class="hljs-number">5</span><br></code></pre></td></tr></table></figure><h3 id="4-3-结构体指针作为函数参数"><a href="#4-3-结构体指针作为函数参数" class="headerlink" title="4.3 结构体指针作为函数参数"></a>4.3 结构体指针作为函数参数</h3><p>结构体变量名代表的是整个集合本身，作为函数参数时传递的整个集合，也就是所有成员，而不是像数组一样被编译器转换成一个指针。如果结构体成员较多，尤其是成员为数组时，传送的时间和空间开销会很大，影响程序的运行效率。所以最好的办法就是使用结构体指针，这时由实参传向形参的只是一个地址，非常快速。</p><p>【示例】计算全班学生的总成绩、平均成绩和以及 140 分以下的人数。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">stu</span>&#123;</span><br>    <span class="hljs-keyword">char</span> *name;  <span class="hljs-comment">//姓名</span><br>    <span class="hljs-keyword">int</span> num;  <span class="hljs-comment">//学号</span><br>    <span class="hljs-keyword">int</span> age;  <span class="hljs-comment">//年龄</span><br>    <span class="hljs-keyword">char</span> group;  <span class="hljs-comment">//所在小组</span><br>    <span class="hljs-keyword">float</span> score;  <span class="hljs-comment">//成绩</span><br>&#125;stus[] = &#123;<br>    &#123;<span class="hljs-string">&quot;Li ping&quot;</span>, <span class="hljs-number">5</span>, <span class="hljs-number">18</span>, <span class="hljs-string">&#x27;C&#x27;</span>, <span class="hljs-number">145.0</span>&#125;,<br>    &#123;<span class="hljs-string">&quot;Zhang ping&quot;</span>, <span class="hljs-number">4</span>, <span class="hljs-number">19</span>, <span class="hljs-string">&#x27;A&#x27;</span>, <span class="hljs-number">130.5</span>&#125;,<br>    &#123;<span class="hljs-string">&quot;He fang&quot;</span>, <span class="hljs-number">1</span>, <span class="hljs-number">18</span>, <span class="hljs-string">&#x27;A&#x27;</span>, <span class="hljs-number">148.5</span>&#125;,<br>    &#123;<span class="hljs-string">&quot;Cheng ling&quot;</span>, <span class="hljs-number">2</span>, <span class="hljs-number">17</span>, <span class="hljs-string">&#x27;F&#x27;</span>, <span class="hljs-number">139.0</span>&#125;,<br>    &#123;<span class="hljs-string">&quot;Wang ming&quot;</span>, <span class="hljs-number">3</span>, <span class="hljs-number">17</span>, <span class="hljs-string">&#x27;B&#x27;</span>, <span class="hljs-number">144.5</span>&#125;<br>&#125;;<br><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">average</span><span class="hljs-params">(struct stu *ps, <span class="hljs-keyword">int</span> len)</span></span>;<br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-keyword">int</span> len = <span class="hljs-keyword">sizeof</span>(stus) / <span class="hljs-keyword">sizeof</span>(struct stu);<br>    average(stus, len);<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">average</span><span class="hljs-params">(struct stu *ps, <span class="hljs-keyword">int</span> len)</span></span>&#123;<br>    <span class="hljs-keyword">int</span> i, num_140 = <span class="hljs-number">0</span>;<br>    <span class="hljs-keyword">float</span> average, sum = <span class="hljs-number">0</span>;<br>    <span class="hljs-keyword">for</span>(i=<span class="hljs-number">0</span>; i&lt;len; i++)&#123;<br>        sum += (ps + i) -&gt; score;<br>        <span class="hljs-keyword">if</span>((ps + i)-&gt;score &lt; <span class="hljs-number">140</span>) num_140++;<br>    &#125;<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;sum=%.2f\naverage=%.2f\nnum_140=%d\n&quot;</span>, sum, sum/<span class="hljs-number">5</span>, num_140);<br>&#125;<br></code></pre></td></tr></table></figure><p>运行结果：<br>sum=707.50<br>average=141.50<br>num_140=2</p><h3 id="4-4-结构体讲解版本2"><a href="#4-4-结构体讲解版本2" class="headerlink" title="4.4 结构体讲解版本2"></a>4.4 结构体讲解版本2</h3><p>可以声明一个指向结构类型对象的指针。</p><hr><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">MyStruct</span></span><br><span class="hljs-class">&#123;</span><br><span class="hljs-keyword">int</span> a;<br><span class="hljs-keyword">int</span> b;<br><span class="hljs-keyword">int</span> c;<br>&#125;;<br><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">MyStruct</span> <span class="hljs-title">ss</span>=</span>&#123;<span class="hljs-number">20</span>,<span class="hljs-number">30</span>,<span class="hljs-number">40</span>&#125;;<br><span class="hljs-comment">//声明了结构对象 ss，并把 ss 的成员初始化为 20，30 和 40。</span><br><br><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">MyStruct</span> *<span class="hljs-title">ptr</span>=</span>&amp;ss;<br><span class="hljs-comment">//声明了一个指向结构对象 ss 的指针。它的类型是MyStruct *,它指向的类型是 MyStruct。</span><br><br><span class="hljs-keyword">int</span> *pstr=(<span class="hljs-keyword">int</span>*)&amp;ss;<br><span class="hljs-comment">//声明了一个指向结构对象 ss 的指针。但是 pstr 和它被指向的类型 ptr 是不同的。</span><br></code></pre></td></tr></table></figure><p>请问怎样通过指针 ptr 来访问 ss 的三个成员变量？<br>答案：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs c">ptr-&gt;a;<br><span class="hljs-comment">//指向运算符，或者可以这们(*ptr).a,建议使用前者</span><br>ptr-&gt;b;<br>ptr-&gt;c;<br></code></pre></td></tr></table></figure><p>又请问怎样通过指针 pstr 来访问 ss 的三个成员变量？<br>答案：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs c">*pstr；<br><span class="hljs-comment">//访问了 ss 的成员 a。</span><br>*(pstr+<span class="hljs-number">1</span>);<br><span class="hljs-comment">//访问了 ss 的成员 b。</span><br>*(pstr+<span class="hljs-number">2</span>)<br><span class="hljs-comment">//访问了 ss 的成员 c。</span><br></code></pre></td></tr></table></figure><p>虽然在编译器上调试过上述代码，但是要知道，这样使用 pstr 来访问结构成员是不正规的。</p><h3 id="指针与函数的关系"><a href="#指针与函数的关系" class="headerlink" title="指针与函数的关系"></a>指针与函数的关系</h3><p>可以把一个指针声明成为一个指向函数的指针。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">fun1</span><span class="hljs-params">(<span class="hljs-keyword">char</span> *, <span class="hljs-keyword">int</span>)</span></span>;<br><span class="hljs-keyword">int</span> (*pfun1)(<span class="hljs-keyword">char</span> *, <span class="hljs-keyword">int</span>);<br>pfun1 = fun1;<br><span class="hljs-keyword">int</span> a = (*pfun1)(<span class="hljs-string">&quot;abcdefg&quot;</span>,<span class="hljs-number">7</span>);<span class="hljs-comment">//通过函数指针调用函数。</span><br></code></pre></td></tr></table></figure><p>可以把指针作为函数的形参。在函数调用语句中，可以用指针表达式来作为实参。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">fun</span><span class="hljs-params">(<span class="hljs-keyword">char</span> *)</span></span>;<br><span class="hljs-keyword">int</span> a;<br><span class="hljs-keyword">char</span> str[]=<span class="hljs-string">&quot;abcdefghijklmn&quot;</span>;<br>a = fun(str);<br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">fun</span><span class="hljs-params">(<span class="hljs-keyword">char</span> *s)</span></span>&#123;<br><span class="hljs-keyword">int</span> num = <span class="hljs-number">0</span>;<br><span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>;;)<br>&#123;<br>num += *s;<br>        s++;<br>&#125;<br><span class="hljs-keyword">return</span> num;<br>&#125;<br></code></pre></td></tr></table></figure><p>这个例子中的函数fun统计一个字符串中各个字符的ASCII码值之和。</p><p>数组的名字也是一个指针。在函数调用中，当把 str作为实参传递给形参 s 后，实际是把 str 的值传递给了 s，s 所指向的地址就和 str 所指向的地址一致</p><p>但是 str 和 s 各自占用各自的存储空间。在函数体内对 s 进行自加 1 运算，并不意味着同时对 str 进行了自加 1 运算。</p><h1 id="五、C语言typedef的用法"><a href="#五、C语言typedef的用法" class="headerlink" title="五、C语言typedef的用法"></a>五、C语言typedef的用法</h1><p><strong>typedef</strong>：C语言允许为一个数据类型起一个新的<strong>别名</strong>，就像给人起“绰号”一样。起别名的目的不是为了提高程序运行效率，而是为了编码方便。</p><p>一个结构体的名字是 stu，要想定义一个结构体变量就得这样写：</p><p>struct stu stu1;</p><p>struct 看起来就是多余的，但不写又会报错。如果为 struct stu 起了一个别名 STU，书写起来就简单了：</p><p>STU stu1;</p><p>使用关键字 <strong>typedef</strong> 可以为类型起一个新的别名。typedef 的用法一般为：</p><p><strong>typedef  oldName  newName</strong>;</p><p>oldName 是类型原来的名字，newName 是类型新的名字。例如：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">int</span> INTEGER;<br>INTEGER a, b; <span class="hljs-comment">//等效于int a, b;</span><br>a = <span class="hljs-number">1</span>;<br>b = <span class="hljs-number">2</span>;<br></code></pre></td></tr></table></figure><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-keyword">typedef</span> <span class="hljs-keyword">int</span> * PTR_INT<br>PTR_INT p1, p2;<span class="hljs-comment">//p1、p2 类型相同，它们都是指向 int 类型的指针。</span><br></code></pre></td></tr></table></figure><p>typedef的最常用的作用就是给结构体变量重命名:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;string.h&gt;</span></span><br><span class="hljs-keyword">typedef</span> <span class="hljs-class"><span class="hljs-keyword">struct</span> _<span class="hljs-title">INFO</span></span><br><span class="hljs-class">&#123;</span><br>        <span class="hljs-keyword">int</span> num; <br>        <span class="hljs-keyword">char</span> str[<span class="hljs-number">256</span>];<br>&#125;INFO;<br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span><br><span class="hljs-function"></span>&#123;<br>        <span class="hljs-class"><span class="hljs-keyword">struct</span> _<span class="hljs-title">INFO</span> <span class="hljs-title">A</span>;</span><br>        INFO B;    <span class="hljs-comment">//通过typedef重命名后的名字INFO与struct _INFO完全等价！</span><br>        A.num = <span class="hljs-number">2014</span>;<br>        <span class="hljs-built_in">strcpy</span>(A.str,<span class="hljs-string">&quot;Welcome to beijing&quot;</span>);<br>        B=A;<br>        <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;This year is %d %s\n&quot;</span>,A.num,A.str);<br>        <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;This year is %d %s\n&quot;</span>,B.num,B.str);<br>        <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>可以看到typedef可以为关键词改名，使改名之后的INFO类型等价于struct _INFO类型，让我们在定义这种结构类型时更方便、省事。</p><h1 id="六、内存操作函数"><a href="#六、内存操作函数" class="headerlink" title="六、内存操作函数"></a>六、内存操作函数</h1><p>在 C 语言中，程序中 malloc 等内存分配函数的使用次数一定要和 free 相等，并一一配对使用。绝对要避免“malloc 两次 free 一次”或者“malloc 一次 free 两次”等情况。</p><p><strong>在 free 之后必须为指针赋一个新值</strong></p><p>在使用指针进行动态内存分配操作时，在指针 p 被 free 释放之后，指针变量本身并没有被删除。如果这时候没有将指针 p 置为 NULL，会让人误以为 p 是个合法的指针而在以后的程序中错误使用它。</p><p><strong>“free(p)”释放的是指针变量 p 所指向的内存，而不是指针变量 p 本身。指针变量 p 并没有被释放，仍然指向原来的存储空间。</strong></p><p>其实，指针只是一个变量，只有程序结束时才被销毁。释放内存空间后，原来指向这块空间的指针还是存在的，只不过现在指针指向的这块内存是不合法的。因此，在释放内存后，必须把指针指向 NULL，以防止指针在后面不小心又被解引用了。</p><h1 id="七、C-引用-amp"><a href="#七、C-引用-amp" class="headerlink" title="七、C++引用 &amp;"></a>七、C++引用 &amp;</h1><h3 id="C-参数传值"><a href="#C-参数传值" class="headerlink" title="C++ 参数传值"></a>C++ 参数传值</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span><br><span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> std;<br><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">Swap</span><span class="hljs-params">(<span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b)</span></span><br><span class="hljs-function"></span>&#123;<br>    <span class="hljs-keyword">int</span> tmp;<br>    <span class="hljs-comment">//以下三行将a、b值互换</span><br>    tmp = a;<br>    a = b;<br>    b = tmp;<br>&#125;<br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span><br><span class="hljs-function"></span>&#123;<br>    <span class="hljs-keyword">int</span> a = <span class="hljs-number">4</span>, b = <span class="hljs-number">5</span>;<br>    <span class="hljs-built_in">Swap</span>(a, b);<br>    cout &lt;&lt; <span class="hljs-string">&quot;After swaping: a = &quot;</span> &lt;&lt; a &lt;&lt; <span class="hljs-string">&quot; b = &quot;</span> &lt;&lt; b &lt;&lt; endl;<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>上面是一段C++ 的语法，运行结果为：<br>After swaping: a = 4 b = 5</p><p>对C++语法不熟悉的话，可以看下面C语言的语法，是一样的效果</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">swap</span><span class="hljs-params">(<span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b)</span></span>&#123;<br>    <span class="hljs-keyword">int</span> tmp;<br>    tmp = a;<br>    a = b;<br>    b = tmp;<br>&#125;<br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span>&#123;<br>    <span class="hljs-keyword">int</span> a = <span class="hljs-number">4</span>, b = <span class="hljs-number">5</span>;<br>    swap(a, b);<br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;后：a = %d, b = %d\n&quot;</span>, a, b);<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>上面代码运行结果为：<br>后：a = 4, b = 5</p><h3 id="C-参数传引用-amp-对参数的修改结果带回来"><a href="#C-参数传引用-amp-对参数的修改结果带回来" class="headerlink" title="C++参数传引用 &amp;  对参数的修改结果带回来"></a>C++参数传引用 &amp;  对参数的修改结果带回来</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string">&lt;iostream&gt;</span></span><br><span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> std;<br><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">Swap</span><span class="hljs-params">(<span class="hljs-keyword">int</span> &amp; a, <span class="hljs-keyword">int</span> &amp; b)</span></span><br><span class="hljs-function"></span>&#123; <span class="hljs-comment">//交换a、b的值</span><br>    <span class="hljs-keyword">int</span> tmp;<br>    tmp = a; a = b; b = tmp;<br>&#125;<br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span><br><span class="hljs-function"></span>&#123;<br>    <span class="hljs-keyword">int</span> n1 = <span class="hljs-number">100</span>, n2 = <span class="hljs-number">50</span>;<br>    <span class="hljs-built_in">Swap</span>(n1, n2);  <span class="hljs-comment">//n1、n2 的值被交换</span><br>    cout &lt;&lt; n1 &lt;&lt; <span class="hljs-string">&quot; &quot;</span> &lt;&lt; n2 &lt;&lt; endl;  <span class="hljs-comment">//输出 50 100</span><br>&#125;<br></code></pre></td></tr></table></figure><p>因为C++是兼容C语言，所以可以写下面的代码，在C语言中使用C++ 的引用，也就是在变量前加&amp;，但是必须在（.cpp)也就是C++文件中运行。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><br><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">swap</span><span class="hljs-params">(<span class="hljs-keyword">int</span> &amp;a, <span class="hljs-keyword">int</span> &amp;b)</span></span><br><span class="hljs-function"></span>&#123; <span class="hljs-comment">//交换a、b的值</span><br>    <span class="hljs-keyword">int</span> tmp;<br>    tmp = a; <br>    a = b; <br>    b = tmp;<br>&#125;<br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span><br><span class="hljs-function"></span>&#123;<br>    <span class="hljs-keyword">int</span> n1 = <span class="hljs-number">100</span>, n2 = <span class="hljs-number">50</span>;<br>    swap(n1, n2);  <span class="hljs-comment">//n1、n2 的值被交换</span><br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;n1=%d, n2= %d\n&quot;</span>, n1, n2);<br>&#125;<br></code></pre></td></tr></table></figure><p>运行结果为：n1=50, n2= 100</p><p>可以看到结果，使用引用&amp;后，对参数的修改可以带回来</p><p>当然C语言也可以用指针来实现，但是不太方便，代码如下：</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;stdio.h&gt;</span></span><br><br><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">swap</span><span class="hljs-params">(<span class="hljs-keyword">int</span> *a, <span class="hljs-keyword">int</span> *b)</span></span><br><span class="hljs-function"></span>&#123; <span class="hljs-comment">//交换a、b的值</span><br>    <span class="hljs-keyword">int</span> tmp;<br>    tmp = *a; <br>    *a = *b; <br>    *b = tmp;<br>&#125;<br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span></span><br><span class="hljs-function"></span>&#123;<br>    <span class="hljs-keyword">int</span> n1 = <span class="hljs-number">100</span>, n2 = <span class="hljs-number">50</span>;<br>    swap(&amp;n1, &amp;n2);  <span class="hljs-comment">//这里&amp;是指取地址符</span><br>    <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;n1=%d, n2= %d\n&quot;</span>, n1, n2);<br>&#125;<br></code></pre></td></tr></table></figure><p>对C++引用了解到这里即可，下面的介绍还涉及到C++的语法</p><h3 id="C-引用"><a href="#C-引用" class="headerlink" title="C++引用"></a>C++引用</h3><p>引用是 C++ 的新增内容，在实际开发中会经常使用；C++ 用的引用就如同C语言的指针一样重要，但它比指针更加方便和易用，有时候甚至是不可或缺的。</p><p>同指针一样，引用能够减少数据的拷贝，提高数据的传递效率。</p><p>引用的定义方式类似于指针，只是用<code>&amp;</code>取代了<code>*</code>，语法格式为：</p><p>type &amp;name = data;</p><p>type 是被引用的数据的类型，name 是引用的名称，data 是被引用的数据。引用必须在定义的同时初始化，并且以后也要从一而终，不能再引用其它数据，这有点类似于常量（const 变量）。</p><p>下面是一个演示引用的实例：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span><br><span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> std;<br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>&#123;<br>    <span class="hljs-keyword">int</span> a = <span class="hljs-number">99</span>;<br>    <span class="hljs-keyword">int</span> &amp;r = a;<br>    cout &lt;&lt; a &lt;&lt; <span class="hljs-string">&quot;, &quot;</span> &lt;&lt; r &lt;&lt; endl;<br>    cout &lt;&lt; &amp;a &lt;&lt; <span class="hljs-string">&quot;, &quot;</span> &lt;&lt; &amp;r &lt;&lt; endl;<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>运行结果：<br>99, 99<br>0x28ff44, 0x28ff44</p><p>本例中，变量 r 就是变量 a 的引用，它们用来指代同一份数据；也可以说变量 r 是变量 a 的另一个名字。从输出结果可以看出，a 和 r 的地址一样，都是<code>0x28ff44</code>；或者说地址为<code>0x28ff44</code>的内存有两个名字，a 和 r，想要访问该内存上的数据时，使用哪个名字都行。</p><p>注意，引用在定义时需要添加<code>&amp;</code>，在使用时不能添加<code>&amp;</code>，使用时添加<code>&amp;</code>表示取地址。如上面代码所示，第 6 行中的<code>&amp;</code>表示引用，第 8 行中的<code>&amp;</code>表示取地址。除了这两种用法，<code>&amp;</code>还可以表示位运算中的与运算。</p><p>由于引用 r 和原始变量 a 都是指向同一地址，所以通过引用也可以修改原始变量中所存储的数据，请看下面的例子：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span><br><span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> std;<br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>&#123;<br>    <span class="hljs-keyword">int</span> a = <span class="hljs-number">99</span>;<br>    <span class="hljs-keyword">int</span> &amp;r = a;<br>    r = <span class="hljs-number">47</span>;<br>    cout &lt;&lt; a &lt;&lt; <span class="hljs-string">&quot;, &quot;</span> &lt;&lt; r &lt;&lt; endl;<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br></code></pre></td></tr></table></figure><p>运行结果：<br>47, 47</p><p>最终程序输出两个 47，可见原始变量 a 的值已经被引用变量 r 所修改。</p><p>如果读者不希望通过引用来修改原始的数据，那么可以在定义时添加 const 限制，形式为：</p><p>const type &amp;name = value;</p><p>也可以是：</p><p>type const &amp;name = value;</p><p>这种引用方式为常引用</p><h3 id="C-引用作为函数参数"><a href="#C-引用作为函数参数" class="headerlink" title="C++引用作为函数参数"></a>C++引用作为函数参数</h3><p>在定义或声明函数时，我们可以将函数的形参指定为引用的形式，这样在调用函数时就会将实参和形参绑定在一起，让它们都指代同一份数据。如此一来，如果在函数体中修改了形参的数据，那么实参的数据也会被修改，从而拥有“在函数内部影响函数外部数据”的效果。</p><p>至于实参和形参是如何绑定的，我们将在下节中讲解，届时我们会一针见血地阐明引用的本质。</p><p>一个能够展现按引用传参的优势的例子就是交换两个数的值，请看下面的代码：</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">&lt;iostream&gt;</span></span><br><span class="hljs-keyword">using</span> <span class="hljs-keyword">namespace</span> std;<br><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">swap1</span><span class="hljs-params">(<span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b)</span></span>;<br><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">swap2</span><span class="hljs-params">(<span class="hljs-keyword">int</span> *p1, <span class="hljs-keyword">int</span> *p2)</span></span>;<br><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">swap3</span><span class="hljs-params">(<span class="hljs-keyword">int</span> &amp;r1, <span class="hljs-keyword">int</span> &amp;r2)</span></span>;<br><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span><span class="hljs-params">()</span> </span>&#123;<br>    <span class="hljs-keyword">int</span> num1, num2;<br>    cout &lt;&lt; <span class="hljs-string">&quot;Input two integers: &quot;</span>;<br>    cin &gt;&gt; num1 &gt;&gt; num2;<br>    <span class="hljs-built_in">swap1</span>(num1, num2);<br>    cout &lt;&lt; num1 &lt;&lt; <span class="hljs-string">&quot; &quot;</span> &lt;&lt; num2 &lt;&lt; endl;<br>    cout &lt;&lt; <span class="hljs-string">&quot;Input two integers: &quot;</span>;<br>    cin &gt;&gt; num1 &gt;&gt; num2;<br>    <span class="hljs-built_in">swap2</span>(&amp;num1, &amp;num2);<br>    cout &lt;&lt; num1 &lt;&lt; <span class="hljs-string">&quot; &quot;</span> &lt;&lt; num2 &lt;&lt; endl;<br>    cout &lt;&lt; <span class="hljs-string">&quot;Input two integers: &quot;</span>;<br>    cin &gt;&gt; num1 &gt;&gt; num2;<br>    <span class="hljs-built_in">swap3</span>(num1, num2);<br>    cout &lt;&lt; num1 &lt;&lt; <span class="hljs-string">&quot; &quot;</span> &lt;&lt; num2 &lt;&lt; endl;<br>    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>&#125;<br><span class="hljs-comment">//直接传递参数内容</span><br><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">swap1</span><span class="hljs-params">(<span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b)</span> </span>&#123;<br>    <span class="hljs-keyword">int</span> temp = a;<br>    a = b;<br>    b = temp;<br>&#125;<br><span class="hljs-comment">//传递指针</span><br><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">swap2</span><span class="hljs-params">(<span class="hljs-keyword">int</span> *p1, <span class="hljs-keyword">int</span> *p2)</span> </span>&#123;<br>    <span class="hljs-keyword">int</span> temp = *p1;<br>    *p1 = *p2;<br>    *p2 = temp;<br>&#125;<br><span class="hljs-comment">//按引用传参</span><br><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">swap3</span><span class="hljs-params">(<span class="hljs-keyword">int</span> &amp;r1, <span class="hljs-keyword">int</span> &amp;r2)</span> </span>&#123;<br>    <span class="hljs-keyword">int</span> temp = r1;<br>    r1 = r2;<br>    r2 = temp;<br>&#125;<br></code></pre></td></tr></table></figure><p>运行结果：<br>Input two integers: 12 34↙<br>12 34<br>Input two integers: 88 99↙<br>99 88<br>Input two integers: 100 200↙<br>200 100</p><p>本例演示了三种交换变量的值的方法：</p><ol><li><p>swap1() 直接传递参数的内容，不能达到交换两个数的值的目的。对于 swap1() 来说，a、b 是形参，是作用范围仅限于函数内部的局部变量，它们有自己独立的内存，和 num1、num2 指代的数据不一样。调用函数时分别将 num1、num2 的值传递给 a、b，此后 num1、num2 和 a、b 再无任何关系，在 swap1() 内部修改 a、b 的值不会影响函数外部的 num1、num2，更不会改变 num1、num2 的值。</p></li><li><p>swap2() 传递的是指针，能够达到交换两个数的值的目的。调用函数时，分别将 num1、num2 的指针传递给 p1、p2，此后 p1、p2 指向 a、b 所代表的数据，在函数内部可以通过指针间接地修改 a、b 的值。</p></li><li><p>swap3() 是按引用传递，能够达到交换两个数的值的目的。调用函数时，分别将 r1、r2 绑定到 num1、num2 所指代的数据，此后 r1 和 num1、r2 和 num2 就都代表同一份数据了，通过 r1 修改数据后会影响 num1，通过 r2 修改数据后也会影响 num2。</p></li></ol><p>从以上代码的编写中可以发现，按引用传参在使用形式上比指针更加直观。在以后的 C++ 编程中，我鼓励读者大量使用引用，它一般可以代替指针（当然指针在C++中也不可或缺），C++ 标准库也是这样做的。</p>]]></content>
    
    
    <categories>
      
      <category>专业课</category>
      
      <category>数据结构</category>
      
    </categories>
    
    
    <tags>
      
      <tag>数据结构</tag>
      
      <tag>专业课</tag>
      
      <tag>C语言</tag>
      
    </tags>
    
  </entry>
  
  
  
  <entry>
    <title>PyCharm使用秘籍</title>
    <link href="/2022/01/25/%E7%AC%94%E8%AE%B0/PyCharm%E4%BD%BF%E7%94%A8%E7%A7%98%E7%B1%8D/"/>
    <url>/2022/01/25/%E7%AC%94%E8%AE%B0/PyCharm%E4%BD%BF%E7%94%A8%E7%A7%98%E7%B1%8D/</url>
    
    <content type="html"><![CDATA[<span id="more"></span><h2 id="在Pycharm下为你的Python项目配置Python解释器"><a href="#在Pycharm下为你的Python项目配置Python解释器" class="headerlink" title="在Pycharm下为你的Python项目配置Python解释器"></a>在Pycharm下为你的Python项目配置Python解释器</h2><ol><li>File&gt;Settings&gt;Project:当前项目名&gt;Project Interpreter&gt;add Local</li></ol><h2 id="在Pycharm下创建Python文件、Python模块"><a href="#在Pycharm下创建Python文件、Python模块" class="headerlink" title="在Pycharm下创建Python文件、Python模块"></a>在Pycharm下创建Python文件、Python模块</h2><ol><li>File&gt;New&gt;Python File</li><li>File&gt;New&gt;Python Package</li></ol><h2 id="使用Pycharm安装Python第三方模块"><a href="#使用Pycharm安装Python第三方模块" class="headerlink" title="使用Pycharm安装Python第三方模块"></a>使用Pycharm安装Python第三方模块</h2><ol><li>File&gt;Settings&gt;Project:当前项目名&gt;Project Interpreter&gt;点击右侧绿色小加号</li></ol><h2 id="Pycharm基本设置，例如不使用tab、tab-4空格、字体、字体颜色、主题、脚本头设置、显示行号等。如何导出和导入自定义设置。"><a href="#Pycharm基本设置，例如不使用tab、tab-4空格、字体、字体颜色、主题、脚本头设置、显示行号等。如何导出和导入自定义设置。" class="headerlink" title="Pycharm基本设置，例如不使用tab、tab=4空格、字体、字体颜色、主题、脚本头设置、显示行号等。如何导出和导入自定义设置。"></a>Pycharm基本设置，例如不使用tab、tab=4空格、字体、字体颜色、主题、脚本头设置、显示行号等。如何导出和导入自定义设置。</h2><ol><li>不使用tab、tab=4空格：Editor&gt;Code Style&gt;Python</li><li>字体、字体颜色：Edit&gt;Colors &amp; Fonts&gt;Python</li><li>关闭自动更新：Appearance &amp; Behavior&gt;System Settings&gt;Updates</li><li>脚本头设置：Edit&gt;File and Code Templates&gt;Python Script 注：其他类似</li><li>显示行号：Edit&gt;General&gt;Appearance&gt;Show line numbers 注：2016.2默认显示行号</li><li>右侧竖线是PEP8的代码规范，提示一行不要超过120个字符</li><li>导出、导入你自定义的配置： File&gt;Export Settings、Import Settings</li></ol><h2 id="常用快捷键，例如复制当前行、删除当前行、批量注释、缩进、查找和替换。"><a href="#常用快捷键，例如复制当前行、删除当前行、批量注释、缩进、查找和替换。" class="headerlink" title="常用快捷键，例如复制当前行、删除当前行、批量注释、缩进、查找和替换。"></a>常用快捷键，例如复制当前行、删除当前行、批量注释、缩进、查找和替换。</h2><ol><li>Ctrl + D：复制当前行</li><li>Ctrl + E：删除当前行</li><li>Shift + Enter：快速换行</li><li>Ctrl + /：快速注释（选中多行后可以批量注释）</li><li>Tab：缩进当前行（选中多行后可以批量缩进）</li><li>Shift + Tab：取消缩进（选中多行后可以批量取消缩进）</li><li>Ctrl + F：查找</li><li>Ctrl + H：替换</li></ol><h2 id="Pycharm安装插件，例如Markdown-support、数据库支持插件等。"><a href="#Pycharm安装插件，例如Markdown-support、数据库支持插件等。" class="headerlink" title="Pycharm安装插件，例如Markdown support、数据库支持插件等。"></a>Pycharm安装插件，例如Markdown support、数据库支持插件等。</h2><ol><li>Plugins&gt;Browse repositories（下方三个按钮中间那个）&gt;搜索‘markdown support’&gt;install</li><li>右上角View有三个选项可选，一般我们都用中间那个左侧编写，右侧实时预览</li></ol><h2 id="Git配置？"><a href="#Git配置？" class="headerlink" title="Git配置？"></a>Git配置？</h2><ol><li>需要本地安装好Git</li><li>Version Control&gt;Git</li><li>配置了Git等版本控制系统之后，可以很方便的diff查看文件的不用</li></ol><h2 id="常用操作指南。例如复制文件路径、在文件管理器中打开、快速定位、查看模块结构视图、tab批量换space、TODO的使用、Debug的使用。"><a href="#常用操作指南。例如复制文件路径、在文件管理器中打开、快速定位、查看模块结构视图、tab批量换space、TODO的使用、Debug的使用。" class="headerlink" title="常用操作指南。例如复制文件路径、在文件管理器中打开、快速定位、查看模块结构视图、tab批量换space、TODO的使用、Debug的使用。"></a>常用操作指南。例如复制文件路径、在文件管理器中打开、快速定位、查看模块结构视图、tab批量换space、TODO的使用、Debug的使用。</h2><ol><li>复制文件路径：左侧文件列表右键选中的文件&gt;Copy Path</li><li>在文件管理器中打开：右键选中的文件&gt;往下找到Show In Explorer</li><li>快速定位：Ctrl + 某些内建模块之后，点击在源文件中展开</li><li>查看结构：IDE左侧边栏Structure 查看当前项目的结构</li><li>tab批量换space：Edit&gt;Convert Indents</li><li>TODO的使用：# TODO 要记录的事情</li><li>Debug设置断点，直接点击行号与代码之间的空白处即可设置断点</li><li>Tab页上右键&gt;Move Right（Down），把当前Tab页移到窗口右边（下边），方便对比</li><li>文件中右键&gt;Local History能够查看文件修改前后的对比</li><li>IDE右下角能看到一些有用的信息，光标当前在第几行的第几个字符、当前回车换行、当前编码类型、当前Git分支</li><li>IDE右侧边栏&gt;Database</li></ol><h2 id="如何去掉烦人的波浪线？PEP8又是什么？"><a href="#如何去掉烦人的波浪线？PEP8又是什么？" class="headerlink" title="如何去掉烦人的波浪线？PEP8又是什么？"></a>如何去掉烦人的波浪线？PEP8又是什么？</h2><ol><li>单独一行的注释：#+1空格+注释内容</li><li>代码后跟着的注释：2空格+#+1空格+注释内容</li><li>牢记快捷键 <code>ctrl+alt+L</code></li></ol><h2 id="SSH-Terminal：-Default-encoding-UTF-8"><a href="#SSH-Terminal：-Default-encoding-UTF-8" class="headerlink" title="SSH Terminal： Default encoding:UTF-8"></a>SSH Terminal： Default encoding:UTF-8</h2><ol><li>Settings&gt;Tools&gt;SSH Terminal&gt;最后一行Default encoding:选择UTF-8</li></ol><h2 id="善用搜索！善用搜索！善用搜索！"><a href="#善用搜索！善用搜索！善用搜索！" class="headerlink" title="善用搜索！善用搜索！善用搜索！"></a>善用搜索！善用搜索！善用搜索！</h2><ol><li>遇到不懂问题，先自己搜索。这样才记得更牢！</li><li>推荐使用sogou英文搜索<a href="http://english.sogou.com/">http://english.sogou.com/</a></li></ol>]]></content>
    
    
    <categories>
      
      <category>pycharm</category>
      
    </categories>
    
    
    <tags>
      
      <tag>pycharm</tag>
      
    </tags>
    
  </entry>
  
  
  
  <entry>
    <title>GitHub够用教程</title>
    <link href="/2022/01/22/%E7%AC%94%E8%AE%B0/GitHub%E5%A4%9F%E7%94%A8%E6%95%99%E7%A8%8B/"/>
    <url>/2022/01/22/%E7%AC%94%E8%AE%B0/GitHub%E5%A4%9F%E7%94%A8%E6%95%99%E7%A8%8B/</url>
    
    <content type="html"><![CDATA[<h1 id="Github够用教程"><a href="#Github够用教程" class="headerlink" title="Github够用教程"></a>Github够用教程</h1><h2 id="git和Github是什么"><a href="#git和Github是什么" class="headerlink" title="git和Github是什么"></a>git和Github是什么</h2><p>git是一个运行在你电脑上的版本控制软件，Github是基于git打造的网站</p><p>git的三个概念：commit 提交/ repository 仓库/ branch 分支</p><span id="more"></span><h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><ul><li>git  <a href="https://gitforwindows.org/">https://gitforwindows.org/</a></li><li>vscode  <a href="https://code.visualstudio.com/">https://code.visualstudio.com/</a></li></ul><h2 id="看别人的项目"><a href="#看别人的项目" class="headerlink" title="看别人的项目"></a>看别人的项目</h2><p>GoGoCode 项目地址：<a href="https://github.com/thx/gogocode">https://github.com/thx/gogocode</a></p><p>git clone <a href="https://github.com/thx/gogocode.git">https://github.com/thx/gogocode.git</a></p><h3 id="关注几个地方"><a href="#关注几个地方" class="headerlink" title="关注几个地方"></a>关注几个地方</h3><p>Star</p><p>README.md</p><p>issue</p><p>LICENSE</p><h2 id="提升github速度的方法"><a href="#提升github速度的方法" class="headerlink" title="提升github速度的方法"></a>提升github速度的方法</h2><h3 id="1-利用镜像提高clone速度"><a href="#1-利用镜像提高clone速度" class="headerlink" title="1. 利用镜像提高clone速度"></a>1. 利用镜像提高clone速度</h3><p>在github.com后面添加 <strong>.cnpmjs.org</strong></p><figure class="highlight bash"><table><tr><td class="gutter"><div class="code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><pre><code class="hljs bash">git <span class="hljs-built_in">clone</span> https://github.com.cnpmjs.org/thx/gogocode.git<br></code></pre></td></tr></table></figure><h3 id="2-使用码云作为中转站"><a href="#2-使用码云作为中转站" class="headerlink" title="2. 使用码云作为中转站"></a>2. 使用码云作为中转站</h3><h3 id="3-比较适合单一的文件"><a href="#3-比较适合单一的文件" class="headerlink" title="3. 比较适合单一的文件"></a>3. 比较适合单一的文件</h3><p>如单独下载readme文件，若下载地址为：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">https://github.com/thx/gogocode/blob/main/README.md<br></code></pre></td></tr></table></figure><p>将<code>github.com</code>改成<code>cdn.jsdelivr.net/gh</code> 并将<code>/blob/</code>改成<code>@</code>得到：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">https://cdn.jsdelivr.net/gh/thx/gogocode@main/README.md<br></code></pre></td></tr></table></figure><p>就可以直接打开，ctrl+s保存</p><h2 id="找开源项目的一些途径"><a href="#找开源项目的一些途径" class="headerlink" title="找开源项目的一些途径"></a>找开源项目的一些途径</h2><p>• <a href="https://github.com/trending/">https://github.com/trending/</a></p><p>  在这里你可以看到各种不同开发语言的每天/周/月的最热门的 Repositories 和 Developers</p><p>• https:///github.com/521xueweihan/HelloGitHub</p><p>  有趣、入门级的开源项目、开源书籍、实战项目、企业级项目等</p><p>• <a href="https://github.com/ruanyf/weekly">https://github.com/ruanyf/weekly</a></p><p>  记录每周值得分享的科技内容，周五发布</p><p>• <a href="https://www.zhihu.com/column/mm-fe">https://www.zhihu.com/column/mm-fe</a></p><p>  阿里妈妈前端快爆前端新鲜事</p><h2 id="特殊的查找资源小技巧-常用前缀后缀"><a href="#特殊的查找资源小技巧-常用前缀后缀" class="headerlink" title="特殊的查找资源小技巧-常用前缀后缀"></a>特殊的查找资源小技巧-常用前缀后缀</h2><p>• 找百科大全 awesome xxx<br>• 找例子 xxx sample<br>• 找空项目架子 xxx starter / xxx boilerplate<br>• 找教程 xxx tutorial</p><p><img src="https://s2.loli.net/2022/01/22/AcknhXTLDj76alK.png" alt="image-20220122172410705"></p>]]></content>
    
    
    <categories>
      
      <category>github</category>
      
    </categories>
    
    
    <tags>
      
      <tag>github</tag>
      
      <tag>技术分享</tag>
      
    </tags>
    
  </entry>
  
  
  
  <entry>
    <title>hexo建站</title>
    <link href="/2022/01/20/%E7%AC%94%E8%AE%B0/hexo%E5%BB%BA%E7%AB%99/"/>
    <url>/2022/01/20/%E7%AC%94%E8%AE%B0/hexo%E5%BB%BA%E7%AB%99/</url>
    
    <content type="html"><![CDATA[<h1 id="hexo建站记录"><a href="#hexo建站记录" class="headerlink" title="hexo建站记录"></a>hexo建站记录</h1><h2 id="参考教程"><a href="#参考教程" class="headerlink" title="参考教程"></a>参考教程</h2><p><a href="https://zhuanlan.zhihu.com/p/26625249">GitHub+Hexo 搭建个人网站详细教程 - 知乎 (zhihu.com)</a></p><p>记得看下评论，搭建过程遇到问题通过百度解决</p><p><a href="https://tding.top/archives/aad98408.html#more">Hexo 搭建个人博客文章汇总 | 小丁的个人博客 (tding.top)</a></p><span id="more"></span><h2 id="最新主题Fluid"><a href="#最新主题Fluid" class="headerlink" title="最新主题Fluid"></a>最新主题Fluid</h2><p><a href="https://github.com/fluid-dev/hexo-theme-fluid">fluid-dev/hexo-theme-fluid: 一款 Material Design 风格的 Hexo 主题 / An elegant Material-Design theme for Hexo (github.com)</a></p><p>用户文档： <a href="https://hexo.fluid-dev.com/docs/start/">开始使用 | Hexo Fluid (fluid-dev.com)</a></p><p>hexo访问优化：<a href="https://www.julydate.com/post/60859300/">你不爱我了QAQ (julydate.com)</a></p><h2 id="每次使用"><a href="#每次使用" class="headerlink" title="每次使用"></a>每次使用</h2><h3 id="1-打开博客目录blog文件夹"><a href="#1-打开博客目录blog文件夹" class="headerlink" title="1. 打开博客目录blog文件夹"></a>1. 打开博客目录blog文件夹</h3><p>我的文件是在本地目录D:\codeWork\Personal_website\blog</p><h3 id="2-在空白处-shift-右键-在此处打开Powershell窗口"><a href="#2-在空白处-shift-右键-在此处打开Powershell窗口" class="headerlink" title="2. 在空白处 shift+右键 在此处打开Powershell窗口"></a>2. 在空白处 shift+右键 在此处打开Powershell窗口</h3><p><img src="https://s2.loli.net/2022/01/28/G7IP5cvbLsNA6nD.png" alt="image-20220128183949993"></p><h3 id="3-输入命令-hexo-new-文章名称"><a href="#3-输入命令-hexo-new-文章名称" class="headerlink" title="3. 输入命令 hexo new 文章名称"></a>3. 输入命令 hexo new 文章名称</h3><p>新建一篇博客</p><figure class="highlight shell"><table><tr><td class="gutter"><div class="code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><pre><code class="hljs shell">hexo new test<br></code></pre></td></tr></table></figure><p><img src="https://s2.loli.net/2022/01/28/qIazWeDY7l1rtLB.png" alt="image-20220128184355318"></p><p>hexo new 文章名，会默认创建一个以文章名命名的markdown文件，创建默认模板为 blog &gt; scaffolds &gt; post.md</p><h3 id="4-在blog-gt-source-gt-posts-文件夹下"><a href="#4-在blog-gt-source-gt-posts-文件夹下" class="headerlink" title="4. 在blog &gt; source &gt; _posts 文件夹下"></a>4. 在blog &gt; source &gt; _posts 文件夹下</h3><p>打开刚创建的文章test.md</p><h3 id="5-修改文件头信息"><a href="#5-修改文件头信息" class="headerlink" title="5. 修改文件头信息"></a>5. 修改文件头信息</h3><p>图片解释：这里采用了cdn加速的绝对地址，图片放在blog &gt; source &gt; img 文件夹中，图片会随部署时上传到</p><p><a href="https://cdn.jsdelivr.net/gh/MayukeM/MayukeM.github.io@master/img/">https://cdn.jsdelivr.net/gh/MayukeM/MayukeM.github.io@master/img/</a> 这个地址下，加上文件名即可使用</p><p><a href="GitHub%E5%A4%9F%E7%94%A8%E6%95%99%E7%A8%8B.md#%E6%8F%90%E5%8D%87github%E9%80%9F%E5%BA%A6%E7%9A%84%E6%96%B9%E6%B3%95#3%20%E6%AF%94%E8%BE%83%E9%80%82%E5%90%88%E5%8D%95%E4%B8%80%E7%9A%84%E6%96%87%E4%BB%B6">3 github加速 比较适合单一的文件</a></p><ul><li>index_img 是首页文章小图</li><li>banner_img 是文章内页顶部大图</li></ul><figure class="highlight subunit"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><code class="hljs subunit">title: test 文件名称默认与创建时的保持一致<br>index_img: https://cdn.jsdelivr.net/gh/MayukeM/MayukeM.github.io@master/img/example.png <br>banner_img: &#x27;https://cdn.jsdelivr.net/gh/MayukeM/MayukeM.github.io@master/img/b2.png&#x27;<br><span class="hljs-keyword">tags:</span>可以添加多个标签<br>  - tag1<br>  - tag2<br>categories:分类是层级关系<br>  - cate1<br>  - cate1.1<br>date: 2022<span class="hljs-string">-01</span><span class="hljs-string">-28</span> 18:41:52<br></code></pre></td></tr></table></figure><p>文章概况，或者文章的前几行</p><p><code>&lt;!-- more --&gt;</code></p><p>文章主体内容</p><h3 id="6-部署"><a href="#6-部署" class="headerlink" title="6. 部署"></a>6. 部署</h3><ul><li>输入命令 hexo g -d  一键部署</li></ul><blockquote><p>hexo g 生成静态文件（generate)<br>hexo s 启动服务器（server) 本地访问<a href="http://localhost:4000/">http://localhost:4000/</a><br>hexo d 部署（deploy)</p></blockquote><h2 id="我的博客"><a href="#我的博客" class="headerlink" title="我的博客"></a>我的博客</h2><p><a href="https://mayuke.xyz/">我的博客 (mayuke.xyz)</a></p><h2 id="绑定域名"><a href="#绑定域名" class="headerlink" title="绑定域名"></a>绑定域名</h2><p><a href="https://tding.top/archives/b48e2719.html">GitHub Pages 绑定域名 | 小丁的个人博客 (tding.top)</a></p><h2 id="域名购买"><a href="#域名购买" class="headerlink" title="域名购买"></a>域名购买</h2><p><a href="https://www.namesilo.com/">https://www.namesilo.com/</a></p><p><a href="https://zhuanlan.zhihu.com/p/33921436">Namesilo 域名购买及使用教程（附 Namesilo 优惠码） - 知乎 (zhihu.com)</a></p><h2 id="域名解析"><a href="#域名解析" class="headerlink" title="域名解析"></a>域名解析</h2><p> <a href="https://console.dnspod.cn/">管理控制台 - DNSPod</a></p><h2 id="GitHub项目"><a href="#GitHub项目" class="headerlink" title="GitHub项目"></a>GitHub项目</h2><p><a href="https://github.com/MayukeM/MayukeM.github.io">MayukeM/MayukeM.github.io: It is my personal website.</a></p><p><a href="https://zhuanlan.zhihu.com/p/143581449">一个极简、优美的Hexo主题：Coder - 知乎 (zhihu.com)</a></p><h2 id="latex公式"><a href="#latex公式" class="headerlink" title="latex公式"></a>latex公式</h2><p><a href="https://github.com/hexojs/hexo-math">hexojs/hexo-math: A hexo plugin that uses MathJax to render math equations. (github.com)</a></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs text">&#123;% mathjax %&#125; \frac&#123;1&#125;&#123;x^2-1&#125; &#123;% endmathjax %&#125;<br></code></pre></td></tr></table></figure><p>这是<mjx-container class="MathJax" jax="SVG"><svg style="vertical-align: -0.985ex;" xmlns="http://www.w3.org/2000/svg" width="4.653ex" height="2.942ex" role="img" focusable="false" viewBox="0 -864.9 2056.8 1300.3" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><path id="MJX-1-TEX-N-31" d="M213 578L200 573Q186 568 160 563T102 556H83V602H102Q149 604 189 617T245 641T273 663Q275 666 285 666Q294 666 302 660V361L303 61Q310 54 315 52T339 48T401 46H427V0H416Q395 3 257 3Q121 3 100 0H88V46H114Q136 46 152 46T177 47T193 50T201 52T207 57T213 61V578Z"></path><path id="MJX-1-TEX-I-1D465" d="M52 289Q59 331 106 386T222 442Q257 442 286 424T329 379Q371 442 430 442Q467 442 494 420T522 361Q522 332 508 314T481 292T458 288Q439 288 427 299T415 328Q415 374 465 391Q454 404 425 404Q412 404 406 402Q368 386 350 336Q290 115 290 78Q290 50 306 38T341 26Q378 26 414 59T463 140Q466 150 469 151T485 153H489Q504 153 504 145Q504 144 502 134Q486 77 440 33T333 -11Q263 -11 227 52Q186 -10 133 -10H127Q78 -10 57 16T35 71Q35 103 54 123T99 143Q142 143 142 101Q142 81 130 66T107 46T94 41L91 40Q91 39 97 36T113 29T132 26Q168 26 194 71Q203 87 217 139T245 247T261 313Q266 340 266 352Q266 380 251 392T217 404Q177 404 142 372T93 290Q91 281 88 280T72 278H58Q52 284 52 289Z"></path><path id="MJX-1-TEX-N-32" d="M109 429Q82 429 66 447T50 491Q50 562 103 614T235 666Q326 666 387 610T449 465Q449 422 429 383T381 315T301 241Q265 210 201 149L142 93L218 92Q375 92 385 97Q392 99 409 186V189H449V186Q448 183 436 95T421 3V0H50V19V31Q50 38 56 46T86 81Q115 113 136 137Q145 147 170 174T204 211T233 244T261 278T284 308T305 340T320 369T333 401T340 431T343 464Q343 527 309 573T212 619Q179 619 154 602T119 569T109 550Q109 549 114 549Q132 549 151 535T170 489Q170 464 154 447T109 429Z"></path><path id="MJX-1-TEX-N-2212" d="M84 237T84 250T98 270H679Q694 262 694 250T679 230H98Q84 237 84 250Z"></path></defs><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="scale(1,-1)"><g data-mml-node="math"><g data-mml-node="mfrac"><g data-mml-node="mn" transform="translate(851.6,394) scale(0.707)"><use data-c="31" xlink:href="#MJX-1-TEX-N-31"></use></g><g data-mml-node="mrow" transform="translate(220,-377.4) scale(0.707)"><g data-mml-node="msup"><g data-mml-node="mi"><use data-c="1D465" xlink:href="#MJX-1-TEX-I-1D465"></use></g><g data-mml-node="mn" transform="translate(605,289) scale(0.707)"><use data-c="32" xlink:href="#MJX-1-TEX-N-32"></use></g></g><g data-mml-node="mo" transform="translate(1008.6,0)"><use data-c="2212" xlink:href="#MJX-1-TEX-N-2212"></use></g><g data-mml-node="mn" transform="translate(1786.6,0)"><use data-c="31" xlink:href="#MJX-1-TEX-N-31"></use></g></g><rect width="1816.8" height="60" x="120" y="220"></rect></g></g></g></svg></mjx-container>公式</p><h2 id="遇到问题"><a href="#遇到问题" class="headerlink" title="遇到问题"></a>遇到问题</h2><figure class="highlight pgsql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs pgsql">fatal: unable <span class="hljs-keyword">to</span> <span class="hljs-keyword">access</span> <span class="hljs-string">&#x27;https://github.com/MayukeM/MayukeM.github.io.git/&#x27;</span>: OpenSSL SSL_read: <span class="hljs-keyword">Connection</span> was <span class="hljs-keyword">reset</span>, errno <span class="hljs-number">10054</span><br></code></pre></td></tr></table></figure><p>部署失败多试几次就好，一般是网络问题</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs bash">git config --global http.sslVerify <span class="hljs-string">&quot;false&quot;</span><br>git config --global --<span class="hljs-built_in">unset</span> http.proxy<br>git config --global --<span class="hljs-built_in">unset</span> https.proxy<br></code></pre></td></tr></table></figure><p><a href="https://github.com/ineo6/hosts">ineo6/hosts: GitHub最新hosts。解决GitHub图片无法显示，加速GitHub网页浏览。</a></p><p><a href="https://blog.csdn.net/li_magic/article/details/83140986">(55条消息) windows 下安装GIT 屏蔽ssl证书校验_li_magic的博客-CSDN博客_git关闭ssl证书验证</a></p><p><img src="https://s2.loli.net/2022/01/20/HWV3TYSkjI2MOEe.png" alt="1"></p>]]></content>
    
    
    <categories>
      
      <category>博客</category>
      
    </categories>
    
    
    <tags>
      
      <tag>博客</tag>
      
    </tags>
    
  </entry>
  
  
  
  <entry>
    <title>Hello World</title>
    <link href="/2022/01/19/%E7%AC%94%E8%AE%B0/hello-world/"/>
    <url>/2022/01/19/%E7%AC%94%E8%AE%B0/hello-world/</url>
    
    <content type="html"><![CDATA[<p>Welcome to <a href="https://hexo.io/">Hexo</a>! This is your very first post. Check <a href="https://hexo.io/docs/">documentation</a> for more info. If you get any problems when using Hexo, you can find the answer in <a href="https://hexo.io/docs/troubleshooting.html">troubleshooting</a> or you can ask me on <a href="https://github.com/hexojs/hexo/issues">GitHub</a>.</p><h2 id="Quick-Start"><a href="#Quick-Start" class="headerlink" title="Quick Start"></a>Quick Start</h2><h3 id="Create-a-new-post"><a href="#Create-a-new-post" class="headerlink" title="Create a new post"></a>Create a new post</h3><figure class="highlight bash"><table><tr><td class="gutter"><div class="code-wrapper"><pre><span class="line">1</span><br></pre></div></td><td class="code"><pre><code class="hljs bash">$ hexo new <span class="hljs-string">&quot;My New Post&quot;</span><br></code></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/writing.html">Writing</a></p><span id="more"></span><h3 id="Run-server"><a href="#Run-server" class="headerlink" title="Run server"></a>Run server</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ hexo server<br></code></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/server.html">Server</a></p><h3 id="Generate-static-files"><a href="#Generate-static-files" class="headerlink" title="Generate static files"></a>Generate static files</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ hexo generate<br></code></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/generating.html">Generating</a></p><h3 id="Deploy-to-remote-sites"><a href="#Deploy-to-remote-sites" class="headerlink" title="Deploy to remote sites"></a>Deploy to remote sites</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">$ hexo deploy<br></code></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/one-command-deployment.html">Deployment</a></p>]]></content>
    
    
    <categories>
      
      <category>博客</category>
      
    </categories>
    
    
    <tags>
      
      <tag>博客</tag>
      
    </tags>
    
  </entry>
  
  
  
  <entry>
    <title>windows常用快捷键</title>
    <link href="/2021/01/15/%E7%AC%94%E8%AE%B0/windows%E5%B8%B8%E7%94%A8%E5%BF%AB%E6%8D%B7%E9%94%AE/"/>
    <url>/2021/01/15/%E7%AC%94%E8%AE%B0/windows%E5%B8%B8%E7%94%A8%E5%BF%AB%E6%8D%B7%E9%94%AE/</url>
    
    <content type="html"><![CDATA[<h1 id="键盘快捷键"><a href="#键盘快捷键" class="headerlink" title="键盘快捷键"></a>键盘快捷键</h1><p><a href="https://www.cnblogs.com/sao-di-seng/p/5632209.html">https://www.cnblogs.com/sao-di-seng/p/5632209.html</a><br>Vim编辑器<br><a href="http://blog.sina.com.cn/s/blog_46dac66f010005kw.html">http://blog.sina.com.cn/s/blog_46dac66f010005kw.html</a>  </p><p>快捷键Ctrl + Shift + Q，然后回车，直接电脑滑动关机<br>进入微信目录，地址栏输入cmd弹出黑框start WeChat.exe &amp; WeChat.exe 多开微信</p><span id="more"></span><table><thead><tr><th align="center">快捷键</th><th align="center">作用</th></tr></thead><tbody><tr><td align="center">Alt+Tab</td><td align="center">窗口切换</td></tr><tr><td align="center">F4</td><td align="center">关闭窗口，关机</td></tr><tr><td align="center">Ctrl+Alt+方向键</td><td align="center">窗口转向</td></tr><tr><td align="center">Alt+空格 C</td><td align="center">关闭窗口</td></tr><tr><td align="center">Alt+回车</td><td align="center">查看文件属性</td></tr><tr><td align="center">Ctrl+Shift+拖动</td><td align="center">创建快捷键</td></tr><tr><td align="center">Win+L</td><td align="center">锁屏（Lock）</td></tr><tr><td align="center">Win+D</td><td align="center">桌面（Desktop）</td></tr><tr><td align="center">Win+E</td><td align="center">资源管理器（Explorer）</td></tr><tr><td align="center">Win+S</td><td align="center">搜索</td></tr><tr><td align="center">Win+M</td><td align="center">最小化所有窗口</td></tr><tr><td align="center">Win+N</td><td align="center">快速笔记（OneNote）</td></tr><tr><td align="center">Win+W</td><td align="center">便笺 草图板 屏幕草图</td></tr><tr><td align="center">Win+T</td><td align="center">切换任务栏应用</td></tr><tr><td align="center">Win+U</td><td align="center">显示设置</td></tr><tr><td align="center">Win+I</td><td align="center">windows设置</td></tr><tr><td align="center">Win+R</td><td align="center">启动运行</td></tr><tr><td align="center">Win+方向键</td><td align="center">控制窗体大小</td></tr><tr><td align="center">win+tab 左上角新建桌面</td><td align="center">新建桌面</td></tr><tr><td align="center">ctrl + win + 方向键</td><td align="center">切换桌面</td></tr></tbody></table><h2 id="闪电启动软件的秘密"><a href="#闪电启动软件的秘密" class="headerlink" title="闪电启动软件的秘密"></a>闪电启动软件的秘密</h2><ol><li><p>在D盘建立一个文件夹，命名为QuickStart或者你喜欢的名字。</p></li><li><p>把桌面的软件快捷方式图标放到QuickStart文件夹中，并重命名成自己能记住的缩写，不重复即可。比如：</p></li></ol><table><thead><tr><th>软件名称</th><th>缩写</th></tr></thead><tbody><tr><td>腾讯QQ</td><td>qq</td></tr><tr><td>Mozilla FireFox</td><td>ff</td></tr><tr><td>Visual Studio</td><td>vs</td></tr><tr><td>SQL Server</td><td>sql</td></tr></tbody></table><ol start="3"><li><p>给QuickStart文件夹建立一个快捷方式，然后重命名为qs，并且把这个快捷方式也放到QuickStart文件夹中</p></li><li><p>在桌面对“我的电脑”点右键，然后选择属性，弹出系统属性对话框。点击左边的“高级系统设置”，在系统属性对话框中，点击“环境变量”按钮，在系统变量列表中找到Path项，然后点击“编辑”按钮，在编辑对话框中新增输入路径“D:\QuickStart”，然后一路点击“确定”按钮，关闭所有对话框。</p></li><li><p>按下Win+R键，调用运行对话框。在运行对话框中输入qq，如果你的电脑够快的话，马上就会弹出QQ的登录界面。输入qs，就会打开D:\QuickStart文件夹。</p></li><li><p>当你新安装了软件，需要把快捷方式添加进来，用qs命令就可以很快打开QuickStart文件夹。</p></li><li><p>当你有经常用到的文件夹，也可以把它的快捷方式放到QuickStart中，很方便就可以打开。</p></li></ol><figure class="highlight markdown"><table><tr><td class="gutter"><div class="code-wrapper"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></div></td><td class="code"><pre><code class="hljs markdown">Win+R运行输入<br><br>-自定义<br><span class="hljs-code">qs快速打开软件快捷方式文件夹</span><br><span class="hljs-code">rs最近文件</span><br><span class="hljs-code">    ff火狐浏览器</span><br><span class="hljs-code">    timTim</span><br><span class="hljs-code">    txsp腾讯视频</span><br><span class="hljs-code">    dngj电脑管家</span><br><span class="hljs-code">    bdwp百度网盘</span><br><span class="hljs-code">    pan百度网盘破解版</span><br><span class="hljs-code">    psPS</span><br><span class="hljs-code">    </span><br><span class="hljs-code">-常用运行命令</span><br><span class="hljs-code">    winwordWord </span><br><span class="hljs-code">    excelExcel</span><br><span class="hljs-code">    onenoteOneNote</span><br><span class="hljs-code"></span><br><span class="hljs-code">    notepad 记事本  </span><br><span class="hljs-code">    mspaint 绘图板 </span><br><span class="hljs-code">    write    写字板</span><br><span class="hljs-code"></span><br><span class="hljs-code">    regedit 注册表</span><br><span class="hljs-code">    mstsc    远程桌面</span><br><span class="hljs-code"></span><br><span class="hljs-code">    cmd命令行 之后输入</span><br><span class="hljs-code">    shutdown -s -t 00 立即关机</span><br></code></pre></td></tr></table></figure><p>下面是用Au3实现的用Alt+Q调用“运行”的代码：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs bash">HotKeySet(<span class="hljs-string">&quot;!q&quot;</span>,<span class="hljs-string">&quot;WinRun&quot;</span>)<br>Func WinRun()<br>Send(<span class="hljs-string">&quot;&#123;LWINDOWN&#125;r&#123;LWINUP&#125;&quot;</span>)<br>WinWait(<span class="hljs-string">&quot;Run&quot;</span>,<span class="hljs-string">&quot;&quot;</span>)<br>If Not WinActive(<span class="hljs-string">&quot;Run&quot;</span>,<span class="hljs-string">&quot;&quot;</span>) Then WinActivate(<span class="hljs-string">&quot;Run&quot;</span>,<span class="hljs-string">&quot;&quot;</span>)<br>EndFunc<br>Do<br>Sleep(500)<br>Until False<br></code></pre></td></tr></table></figure>]]></content>
    
    
    <categories>
      
      <category>技术分享</category>
      
    </categories>
    
    
    <tags>
      
      <tag>技术分享</tag>
      
      <tag>windows</tag>
      
      <tag>快捷键</tag>
      
    </tags>
    
  </entry>
  
  
  
  <entry>
    <title>Markdown语法</title>
    <link href="/2021/01/07/%E7%AC%94%E8%AE%B0/markdown%E8%AF%AD%E6%B3%95/"/>
    <url>/2021/01/07/%E7%AC%94%E8%AE%B0/markdown%E8%AF%AD%E6%B3%95/</url>
    
    <content type="html"><![CDATA[<h1 id="Typora-Markdown语法"><a href="#Typora-Markdown语法" class="headerlink" title="Typora-Markdown语法"></a>Typora-Markdown语法</h1><h2 id="目录列表"><a href="#目录列表" class="headerlink" title="目录列表"></a>目录列表</h2><p>输入<code>[toc]</code>然后回车，将会产生一个目录，这个目录抽取了文章的所有标题，自动更新内容。</p><p>[toc]</p><span id="more"></span><h2 id="1-标题"><a href="#1-标题" class="headerlink" title="1. 标题"></a>1. 标题</h2><figure class="highlight markdown"><table><tr><td class="gutter"><div class="code-wrapper"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></div></td><td class="code"><pre><code class="hljs markdown"><span class="hljs-section"># 一级标题：#+空格+标题+回车 或者ctrl+1</span><br><br><span class="hljs-section">## 二级标题：##+空格+标题+回车 或者Ctrl+2</span><br><br><span class="hljs-section">### 三级标题：###+空格+标题+回车 或者ctrl+3</span><br><br><span class="hljs-section">#### 四级标题：####+空格+标题+回车 或者ctrl+4</span><br><br><span class="hljs-section">##### 五级标题：#####+空格+标题+回车 或者ctrl+5</span><br><br><span class="hljs-section">###### 六级标题：######+空格+标题+回车 或者ctrl+6</span><br></code></pre></td></tr></table></figure><h2 id="2-字体"><a href="#2-字体" class="headerlink" title="2.字体"></a>2.字体</h2><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs markdown"><span class="hljs-strong">**加粗**</span> ctrl+B<br><span class="hljs-emphasis">*斜体*</span> ctrl+I<br><span class="hljs-strong">**<span class="hljs-emphasis">*粗体+斜体<span class="hljs-strong">**<span class="hljs-emphasis">*</span></span></span></span><br><span class="hljs-emphasis"><span class="hljs-strong"><span class="hljs-emphasis"><span class="hljs-strong"><span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">u</span>&gt;</span></span>下划线<span class="xml"><span class="hljs-tag">&lt;/<span class="hljs-name">u</span>&gt;</span></span> crtl+U</span></span></span></span><br><span class="hljs-emphasis"><span class="hljs-strong"><span class="hljs-emphasis"><span class="hljs-strong">~~删除线~~ alt+shift+5</span></span></span></span><br></code></pre></td></tr></table></figure><h2 id="3-引用"><a href="#3-引用" class="headerlink" title="3.引用"></a>3.引用</h2><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs markdown"><span class="hljs-quote">&gt; 在起始位置添加一个大于&gt;符号+空格，表示引用</span><br></code></pre></td></tr></table></figure><blockquote><p>引用别人文章字句时可以使用</p></blockquote><h2 id="4-分割线"><a href="#4-分割线" class="headerlink" title="4.分割线"></a>4.分割线</h2><p>可以用<code>---</code>空格加回车</p><hr><p>也可以<code>***</code>空格加回车（这个分割线占全屏）</p><hr><h2 id="5-图片"><a href="#5-图片" class="headerlink" title="5.图片"></a>5.图片</h2><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs markdown">格式：![<span class="hljs-string">图片名字</span>](<span class="hljs-link">输入图片路径</span>)<br></code></pre></td></tr></table></figure><p><img src="C:/Users/13740/Pictures/Camera Roll/MRV_20201229_13_25_17.jpg" alt="小猫" style="zoom:25%;" />\</p><blockquote><p>图片前敲一个空格，就能自动左对齐</p></blockquote><p><a href="https://zhuanlan.zhihu.com/p/137310314?utm_source=qq&utm_medium=social&utm_oi=1262490802221498368">图床功能</a></p><p><a href="https://baike.baidu.com/item/%E5%9B%BE%E5%BA%8A/10721348?fr=aladdin">图床是什么？</a></p><p><strong>在偏好设置，把图片保存到相对路径的方法</strong></p><p><img src="https://i.loli.net/2021/02/07/QhZ9Bs4NK2gCYAX.png" alt="image-20210131213522562"></p><h2 id="6-超链接"><a href="#6-超链接" class="headerlink" title="6.超链接"></a>6.超链接</h2><p><strong>行内式：</strong></p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs markdown">格式：[<span class="hljs-string">超链接名字</span>](<span class="hljs-link">超链接地址</span>)<br></code></pre></td></tr></table></figure><blockquote><p>按住ctrl点击访问</p></blockquote><p><a href="https://www.baidu.com/">点击跳转</a></p><p><strong>参考式</strong>：</p><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs markdown">格式：[链接一]：http://www.baidu.com<br>[<span class="hljs-string">百度1</span>][<span class="hljs-symbol">链接一</span>]<br>[<span class="hljs-string">百度2</span>][<span class="hljs-symbol">链接一</span>]<br></code></pre></td></tr></table></figure><p><a href="https://www.baidu.com/">百度1</a></p><p><a href="https://www.baidu.com/">百度2</a></p><h2 id="7-列表"><a href="#7-列表" class="headerlink" title="7.列表"></a>7.列表</h2><p><strong>有序列表</strong>： 1+.+空格</p><ol><li>第一</li><li>第二<ol><li>第二点一</li><li>第二点二</li></ol></li></ol><p><strong>无序列表</strong>：-号＋空格</p><ul><li>A</li><li>B</li><li>C</li></ul><h2 id="8-表格"><a href="#8-表格" class="headerlink" title="8.表格"></a>8.表格</h2><ol><li>可直接右键插入表格 ctrl+T</li><li>手打样式 |名字|性别|生日|</li></ol><table><thead><tr><th>名字</th><th>性别</th><th>生日</th></tr></thead><tbody><tr><td></td><td></td><td></td></tr></tbody></table><h2 id="9-代码"><a href="#9-代码" class="headerlink" title="9.代码"></a>9.代码</h2><p>三个```后面加语言类型</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><code class="hljs html">```html 回车<br><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span><br>    <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span><br>        <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">&quot;1.jpg&quot;</span>/&gt;</span><br>    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span><br><span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span><br></code></pre></td></tr></table></figure><p><strong>嵌入代码</strong></p><p>使用``</p><h2 id="10-插入表情"><a href="#10-插入表情" class="headerlink" title="10.插入表情"></a>10.插入表情</h2><p>使用<code>:happy:</code>输入高兴的表情，使用<code>:cry:</code>输入哭的表情，等等</p><p>:happy::sweat::cry:</p><h2 id="11-标注"><a href="#11-标注" class="headerlink" title="11.标注"></a>11.标注</h2><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs markdown">某些人用过了才知道[^注释]<br>[<span class="hljs-symbol">^注释</span>]:<span class="hljs-link">Somebody that I used to know.</span><br></code></pre></td></tr></table></figure><p>某些人用过了才知道[^注释]</p><p>[^注释]:Somebody that I used to know.</p><blockquote><p>把鼠标放在<code>注释</code>上，将会有提示内容.</p></blockquote><h2 id="12-任务列表"><a href="#12-任务列表" class="headerlink" title="12.任务列表"></a>12.任务列表</h2><figure class="highlight markdown"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><code class="hljs markdown"><span class="hljs-bullet">-</span> [ ] 吃饭<br><span class="hljs-bullet">-</span> [ ] 逛街<br><span class="hljs-bullet">-</span> [ ] 看电影<br></code></pre></td></tr></table></figure><ul><li><input disabled="" type="checkbox"> 吃饭 </li><li><input disabled="" type="checkbox"> 逛街</li><li><input checked="" disabled="" type="checkbox"> 看电影</li></ul>]]></content>
    
    
    <categories>
      
      <category>技术分享</category>
      
    </categories>
    
    
    <tags>
      
      <tag>技术分享</tag>
      
      <tag>markdown</tag>
      
    </tags>
    
  </entry>
  
  
  
  
</search>
