加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
atom.xml 51.86 KB
一键复制 编辑 原始数据 按行查看 历史
乔乔 提交于 2022-07-02 13:14 . Site updated: 2022-07-02 13:14:19
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>空の青さを知る人は——乔乔</title>
<subtitle>发愁阿龙の收容小站</subtitle>
<link href="http://www.jojohome.cn/atom.xml" rel="self"/>
<link href="http://www.jojohome.cn/"/>
<updated>2022-07-02T05:13:33.596Z</updated>
<id>http://www.jojohome.cn/</id>
<author>
<name>乔乔(Joe/JOJo)</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>STL 容器详解——string 类</title>
<link href="http://www.jojohome.cn/posts/cfcd13d.html"/>
<id>http://www.jojohome.cn/posts/cfcd13d.html</id>
<published>2022-07-02T05:13:46.348Z</published>
<updated>2022-07-02T05:13:33.596Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>@<a href="%E7%9B%AE%E5%BD%95">TOC</a></p><h2 id="传统艺能😎"><a href="#传统艺能😎" class="headerlink" title="传统艺能😎"></a>传统艺能😎</h2><p>小编是双非本科大一菜鸟不赘述,欢迎大佬指点江山(QQ:1319365055)<br>此前博客<a href="https://blog.51cto.com/">点我!点我!请搜索博主 【知晓天空之蓝】</a></p><p>==🎉🎉非科班转码社区诚邀您入驻🎉🎉==<br>小伙伴们,打码路上一路向北,背后烟火,彼岸之前皆是疾苦<br>==一个人的单打独斗不如一群人的砥砺前行==<br>这是我和梦想合伙人组建的社区,诚邀各位有志之士的加入!!<br>社区用户好文均加精(“标兵”文章字数2000+加精,“达人”文章字数1500+加精)<br> 直达: <a href="https://bbs.csdn.net/forums/FKBZM?typeId=22226">社区链接点我</a></p><p> 🎉🎉🎉<font color="orange" size="5">倾力打造转码社区微信公众号🎉🎉🎉<br><img src="https://img-blog.csdnimg.cn/d5a1afe7c7c2424184a62535a1ab2fb2.png#pic_center" alt="在这里插入图片描述"></font></p><font color="orange" size="5"><hr><p><img src="https://img-blog.csdnimg.cn/64fdfd7747b44776bd7a5564daa6d596.png#pic_center" alt="在这里插入图片描述"></p><h2 id="嘛是STL🤔"><a href="#嘛是STL🤔" class="headerlink" title="嘛是STL🤔"></a>嘛是STL🤔</h2><p>STL是Standard Template Library的简称,标准模板库,==它不仅是可复用的组件库,也是一个包罗数据结构与算法的软件框架==。它是惠普实验室(HP)开发的一系列软件的统称,这可能是一个历史上最令人兴奋的工具的最无聊的术语。但是人家本这伟大的开源精神,声明允许任何人修改,拷贝,传播甚至商用但是唯一的条款就是使用者也需要开源。</p><p>STL的目的是标准化组件,这样就不用重新开发,可以使用现成的组件,STL现在是C++的一部分,因此不用额外安装什么。</p><p>惠普作为原始版本,后续悠悠大佬来进行把玩走出了==三个版本==:<br>1.<font color="blue4" size="4"> P.J 版本</font></p><font color="blue4" size="4"><p>P.J.Plauger 开发,继承HP版本,被 windows visual C+采用,不被公开和修改,可读性差,符号命名怪异,所以 windows 一直以来闭源这也是看的出来的。<br>2. <font color="blue4" size="4">RW 版本:</font></p><font color="blue4" size="4"><p>由同名公司开发,继承HP版本,被 C++ builder 采用,不被公开和修改,可读性稍稍好一点,但是 builder 是 20 年前的编译器,当时这还是个C++嘎嘎牛的编译器,只是后面被 vs 这名猛将扳倒了,中道崩殂也是实在可惜。<br>3. <font color="blue4" size="4">SGI 版本:</font></p><font color="blue4" size="4"><p>这是作为STL学习参考的主要版本,继承HP版本,被 g++(Linux) 采用,移植性好并且做了开源,阅读性也是非常的高。后面推荐去阅读==侯捷老师的《STL源码剖析》==,恕我直言不知道侯捷老师,你要说你是学习C++的,那必定是有水分的。<br><img src="https://img-blog.csdnimg.cn/a3b040d40fe643b0b267ffec20a638a1.png#pic_center" alt="在这里插入图片描述"><br><font color="pink" size="4">有人说:为何某些公司不允许使用 C++ STL?</font></p><font color="pink" size="4"><blockquote><p>现在 Powerpoint 早已解禁 STL,源码里面漫山遍野的模板,然而 Word 没有,代码仍然一股汇编味,一个函数调用 20 个参数五个 out…大家自己去细品</p></blockquote><h2 id="内容🤔"><a href="#内容🤔" class="headerlink" title="内容🤔"></a>内容🤔</h2><p><strong>STL包含六大组件</strong>:<br><img src="https://img-blog.csdnimg.cn/79bc25928f4142f29cfa983d498927b7.png#pic_center" alt="在这里插入图片描述"></p><p>所谓的算法和容器就是对应我们常说的算法和数据结构,容器就是数据结构。</p><h2 id="重要性🤔"><a href="#重要性🤔" class="headerlink" title="重要性🤔"></a>重要性🤔</h2><p>C++是一门很棒的语言,唯一的缺陷就是相关的库太少,不是因为大家不想为它写库,而是它的库很难写。而STL是C++v的标准模板库,里面封装了很多经典的算法,再加上是基于模板的,适用于多种数据类型,某种程度上说是通用算法,所以它在C++中的地位很高。就拿咱题目说,一个能用 C++ 解决的题,有些也支持C语言实现,但是一句 STL 能搞定上的在C里面可能会需要搞出二级指针这种属实恶心人的东西。</p><p>学 C++ 不学STL(现在叫标准程序库或许好点,后者对STL有所改进,应该算是STL的超集),一定是你人生一大遗憾,可惜现在很多学校教 C++ 的时候,根本没有提到过STL。</p><p>所以论STL重要性,这个问题本身就是个问题,不清楚 STL 地位的 C++ 学习者什么成分咱就不说了。<br><img src="https://img-blog.csdnimg.cn/4659743a8bbe4af197a6bb9792bc4868.gif#pic_center" alt="在这里插入图片描述"></p><h2 id="string-类🤔"><a href="#string-类🤔" class="headerlink" title="string 类🤔"></a>string 类🤔</h2><p>我为什么想第一个针对学习 string 类?原因很简单,早在C语言阶段就学习了字符串,为了操作方便,C语言标准库提供了一堆有关字符串操作的函数——str 系列函数,但这些函数是和字符串分开的,不太适合OOP的思想,而且底层空间需要用户自己管理,稍不留神就会越界访问。</p><p><img src="https://img-blog.csdnimg.cn/5c0b21d311c74d868da4b00e88799e62.png#pic_center" alt="在这里插入图片描述"><br>从定义来看,string 类是一个 typedef 的模板,而其实库里面并不仅仅只有一种 string,还有下面这些个玩意儿:<br><img src="https://img-blog.csdnimg.cn/56d2c0d2d7a947dea9f3b55c5cca2b6e.png#pic_center" alt="在这里插入图片描述"><br>为什么会有这么多派生?其实这就要牵扯到==编码问题==。我们知道从最早的 ASCII 码到后来的 unicode(统一码也叫万国码,世界语言的映射表),unicode 又包含了 utf-8,utf-16,utf-32,再到后来的 gbk(国标扩展,针对汉字的映射表),其实网络上的敏感词屏蔽机制就是利用了编码。</p><p><font color="blue4" size="4">为什么 string 会设计成模板就是因为原本的 string 管理对象是 char 类型,能够很好的去兼容英文,但是像 gbk 编码的汉字就需要两个字符表示,这时就需要一个新的类来支持汉字,所以我们把 string 搞成模板就是为了适应不同的编码。</font></p><font color="blue4" size="4"><p>他虽然是模板,但是使用时不需要 .h 头文件,直接 </p><blockquote><p>#include<string></string></p></blockquote><p>即可使用。他之所以不加 .h 就是因为C语言已经有一个 string.h 了,这里会产生冲突发生链接错误。当然直接使用 string 类型比如: string a 这种定义方式是错误的,因为C++标准库的东西都是放在 std 标准命名空间的。</p><h2 id="对象的常见构造🤔"><a href="#对象的常见构造🤔" class="headerlink" title="对象的常见构造🤔"></a>对象的常见构造🤔</h2><p>string 类对象的构造方法有上百种,我们不可能全部记住,重点记住几个重要常见的就行了<br><img src="https://img-blog.csdnimg.cn/af8042a0025d42b6a3b4a5f2d8f1d093.png#pic_center" alt="在这里插入图片描述"></p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> string s1<span class="token punctuation">;</span> string <span class="token function">s2</span><span class="token punctuation">(</span><span class="token string">"hello world"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> string <span class="token function">s3</span><span class="token punctuation">(</span>s2<span class="token punctuation">)</span><span class="token punctuation">;</span> string s4 <span class="token operator">=</span> s2<span class="token punctuation">;</span> string <span class="token function">s5</span><span class="token punctuation">(</span><span class="token string">"hello world"</span><span class="token punctuation">,</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//前5个元素得到 hello</span> string <span class="token function">s6</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">,</span><span class="token string">'a'</span><span class="token punctuation">)</span><span class="token comment">//初始化为10个a</span> string <span class="token function">s7</span><span class="token punctuation">(</span>s2<span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token comment">//从 s2 的"w"开始向后拷贝3个</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>注意无参构造 s1 里面并不是什么都没有,从底层来讲 s1 底限也会有一个 ‘\0’ 在里面。</p><p>在 s7 这种构造里面,构造表达式为</p><blockquote><p>string(const string&amp; str,size_t pos,size_t len = npos);</p></blockquote><p>这里的这个 npos 又是个啥?他是个半缺省的声明,这个 npos 其实是一个成员变量<br><img src="https://img-blog.csdnimg.cn/088eb1fcf20a4ab0aacfbd1a39ef19f8.png#pic_center" alt="在这里插入图片描述"><br>这里的 static const size_t npos = -1,-1 的补码是全1,给到无符号数身上就是最大值,npos 内涵就是无符号数的上限范围 4294967295,你有多少就能给你取多少。</p><p>==但是总的来说并不是内容越多越好==,string 类的 106 种成员接口很多都让他在C++中显得非常冗余,陈皓老师的<a href="https://blog.csdn.net/haoel/article/details/1491219?ops_request_misc=&amp;request_id=&amp;biz_id=102&amp;utm_term=string%E7%B1%BB%E6%80%8E%E4%B9%88%E5%95%A6&amp;utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-1-1491219.142%5Ev11%5Econtrol,157%5Ev13%5Enew_3&amp;spm=1018.2226.3001.4187">《STL的 string 类怎么啦》</a>一文中就对他提出了批评。</p><h2 id="string-的遍历🤔"><a href="#string-的遍历🤔" class="headerlink" title="string 的遍历🤔"></a>string 的遍历🤔</h2><p>其实上面对 string 的拷贝啥的都不是问题,真正的问题在于怎么去遍历 string 的每一个字符,比如我们需要做翻转 string 的操作。</p><p>遍历 string 有三种方式:</p><ol><li><font color="blue4" size="4">下标+[] 访问</font></li><font color="blue4" size="4"></font></ol><font color="blue4" size="4"><p>和数组有异曲同工之妙,我们依然可以用循环的方式遍历他</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">for</span><span class="token punctuation">(</span>size_t<span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span>i<span class="token operator">&lt;</span>s1<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">{</span> cout<span class="token operator">&lt;&lt;</span>s1<span class="token punctuation">[</span>i<span class="token punctuation">]</span><span class="token operator">&lt;&lt;</span><span class="token string">" "</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span></span></code></pre><ol start="2"><li><font color="blue4" size="4">迭代器</font></li><font color="blue4" size="4"></font></ol><font color="blue4" size="4"><pre class="line-numbers language-c" data-language="c"><code class="language-c">string<span class="token operator">::</span>iterator it <span class="token operator">=</span> s1<span class="token punctuation">.</span><span class="token function">begin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token keyword">while</span><span class="token punctuation">(</span>it<span class="token operator">!=</span>s1<span class="token punctuation">.</span><span class="token function">end</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">{</span> cout<span class="token operator">&lt;&lt;</span><span class="token operator">*</span>it<span class="token operator">&lt;&lt;</span><span class="token string">" "</span><span class="token punctuation">;</span> <span class="token operator">++</span>it<span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>这里迭代器只做演示,后面我想专题讲解迭代器。现阶段可以认为它是个像指针或者就是指针的东西,s1 里面有一段空间,==begin 返回里面内容的开头位置,而 end 不是最后一个数据而是最后一个数据的下一个位置==,所以他是一个开区间,这里 while 为什么使用 != 而不用 &lt; 呢, != 在这里是一种相对标准的语法,后面的链表或者 map,他们的迭代器并不是原生的而是封装的,用 &lt; 就达不到目的了。</p><ol start="3"><li>之前讲过的范围 for </li></ol><p>范围 for 对于遍历确实方便,毕竟 auto 关键字可以自动识别类型,但是如果有需要进行走动(比如双指针靠拢的遍历)的场景就没什么大用了。</p><h2 id="append🤔"><a href="#append🤔" class="headerlink" title="append🤔"></a>append🤔</h2><p>我们在 string 里面插入单个字符或者批量初始化为同一个字符是可以的,那可不可以插入字符串呢?答案一定是可以的,我们引入了 append 接口。</p><p>append 也和 string 一样接口一大堆,所以我们依然取其精华去其糟粕</p><blockquote><p> string&amp; append (const string&amp; str);<br> string&amp; append (const char* s);</p></blockquote><p>但是我想告诉你,<font color="blue4" size="4">append 并不是最佳人选,真正的利器是 operator+= <font color="0" size="3">,可以直接进行各种操作,又好读又好写何乐不为。</font></font></p><font color="blue4" size="4"><font color="0" size="3"><pre class="line-numbers language-c" data-language="c"><code class="language-c">s <span class="token operator">+=</span> <span class="token string">'a'</span><span class="token punctuation">;</span>s <span class="token operator">+=</span> <span class="token string">'YiGuBiGu'</span><span class="token punctuation">;</span>s <span class="token operator">+=</span> str<span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span></span></code></pre><h2 id="getline🤔"><a href="#getline🤔" class="headerlink" title="getline🤔"></a>getline🤔</h2><p>虽然可以使用 cin 和 &gt;&gt; 运算符来输入字符串,但它可能会导致一些需要注意的问题。</p><p>当 cin 读取数据时,它会传递并忽略任何前导白色空格字符(空格、制表符或换行符)。一旦它接触到第一个非空格字符即开始阅读,当它读取到下一个空白字符时,它将停止读取。他的原型是:</p><blockquote><p>istream&amp; getline ( istream &amp;is , string &amp;str , char delim );</p></blockquote><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token function">getline</span><span class="token punctuation">(</span>cin<span class="token punctuation">,</span>line<span class="token punctuation">)</span><span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>这样就可以获得一个含有空格的字符串了,有人会误将 getline()作为while的判断语句,这样你会无法退出 while 循环!因为你的回车只会终止getline()函数的读入操作,getline()函数终止后又进行while()判断(即判断输入流是否有效,你的输入流当然有效,满足条件),所以又运行getline()函数。</p><h2 id="string的拷贝🤔"><a href="#string的拷贝🤔" class="headerlink" title="string的拷贝🤔"></a>string的拷贝🤔</h2><p>当我们需要将一个 string 内容进行操作时,我不想对他进行改动,那么我们一般会选择 new 一个新空间再用 strcpy 等方法进行拷贝,你可能会疑惑为什么不直接给目标赋值(如下)。<br><img src="https://img-blog.csdnimg.cn/433b7776dbc74d95b946de9c2cd62321.png#pic_center" alt="在这里插入图片描述"></p><p>其实原因很简单,因为 string 是一个常量字符串,我们直接赋值过去也是一个完整的常量字符串个体,它就不支持增删查改这些基本属性了,所以如需操作还请仔细慎重的考虑是否直接赋值。</p><h2 id="两种-swap-🤔"><a href="#两种-swap-🤔" class="headerlink" title="两种 swap 🤔"></a>两种 swap 🤔</h2><p>因为 string 里面有一个 swap 函数,所以我就单独拿出来说一下,这两个 swap 虽然功能都是交换内容但是内涵却不一样,他的的域不同。</p><pre class="line-numbers language-c" data-language="c"><code class="language-c">string <span class="token function">s1</span><span class="token punctuation">(</span><span class="token string">"hahaha"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>string <span class="token function">s2</span><span class="token punctuation">(</span><span class="token string">"xixixi"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>s1<span class="token punctuation">.</span><span class="token function">swap</span><span class="token punctuation">(</span>s2<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">swap</span><span class="token punctuation">(</span>s1<span class="token punctuation">,</span>s2<span class="token punctuation">)</span><span class="token punctuation">;</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>相比之下,上面那个 swap 的效率就会更高,因为他的原理是交换指针,而下面那个 swap 是一个全局函数所以效率就比较低下,他的实现原理其实本质上是深拷贝,等价于这样:<br><img src="https://img-blog.csdnimg.cn/01607396737d4845a311482a03f3a0cf.png#pic_center" alt="在这里插入图片描述"></p><p>今天先到这里吧,润了家人们。</p></font></font></font></font></font></font></font></font></font></font>]]></content>
<summary type="html">带你一命通关C++的STL容器,十分钟手撕 string 类</summary>
<category term="C++" scheme="http://www.jojohome.cn/categories/C/"/>
<category term="STL" scheme="http://www.jojohome.cn/tags/STL/"/>
</entry>
<entry>
<title>C++模板深剖</title>
<link href="http://www.jojohome.cn/posts/c0965d3e.html"/>
<id>http://www.jojohome.cn/posts/c0965d3e.html</id>
<published>2022-07-01T18:41:46.432Z</published>
<updated>2022-07-02T04:47:55.527Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>@<a href="%E7%9B%AE%E5%BD%95">TOC</a></p><h2 id="传统艺能😎"><a href="#传统艺能😎" class="headerlink" title="传统艺能😎"></a>传统艺能😎</h2><p>小编是双非本科大一菜鸟不赘述,欢迎大佬指点江山(QQ:1319365055)<br>此前博客<a href="https://blog.51cto.com/">点我!点我!请搜索博主 【知晓天空之蓝】</a></p><p>==🎉🎉非科班转码社区诚邀您入驻🎉🎉==<br>小伙伴们,打码路上一路向北,背后烟火,彼岸之前皆是疾苦<br>==一个人的单打独斗不如一群人的砥砺前行==<br>这是我和梦想合伙人组建的社区,诚邀各位有志之士的加入!!<br>社区用户好文均加精(“标兵”文章字数2000+加精,“达人”文章字数1500+加精)<br> 直达: <a href="https://bbs.csdn.net/forums/FKBZM?typeId=22226">社区链接点我</a></p><p> 🎉🎉🎉<font color="orange" size="5">倾力打造转码社区微信公众号🎉🎉🎉<br><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207020243063.png" alt="在这里插入图片描述"></font></p><font color="orange" size="5"><hr><p><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207020243267.png" alt="在这里插入图片描述"></p><h1 id="泛型编程🤔"><a href="#泛型编程🤔" class="headerlink" title="泛型编程🤔"></a>泛型编程🤔</h1><p>C++ 又一个针对C语言不足提出的概念叫泛型编程,即我们的代码不再只是针对一种类型而是面对各种类型,它使用的基础就是C++的==模板==。</p><p>我们实现一个场景时,很多代码是相似的,但我对于 int ,double,char ,不同的自义定类型都要去写一份代码,属实没有意思,所以C++给出了模板概念。比如古代印刷术出来之前,书的印刷是靠手抄,一遍一遍抄不仅慢还容易错字,古人就想出了将字刻在石板上雕版印刷即可,这就类似于模板。</p><p>模板是创建泛型类或函数的蓝图或公式。库容器,比如迭代器和算法,都是泛型编程的例子,它们都使用了模板的概念。</p><p>每个容器都有一个单一的定义,比如向量,我们可以定义许多不同类型的向量,比如 vector <int> 或 vector <string>。</string></int></p><h2 id="函数模板🤔"><a href="#函数模板🤔" class="headerlink" title="函数模板🤔"></a>函数模板🤔</h2><p>定义格式如下:</p><blockquote><p>template&lt;typename T,typename T2,……,typename Tn&gt;</p></blockquote><p>就拿简单的交换函数为例:</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token comment">//template&lt;class T&gt;</span>template<span class="token operator">&lt;</span>typename T<span class="token operator">&gt;</span><span class="token comment">//这里和class T没有区别</span><span class="token keyword">void</span> <span class="token function">Swap</span><span class="token punctuation">(</span>T<span class="token operator">&amp;</span> a<span class="token punctuation">,</span>T<span class="token operator">&amp;</span> b<span class="token punctuation">)</span><span class="token punctuation">{</span> T tem <span class="token operator">=</span> a<span class="token punctuation">;</span> a <span class="token operator">=</span> b<span class="token punctuation">;</span> b <span class="token operator">=</span> tem<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token comment">//函数模板</span><span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">int</span> a <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span>b <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span> <span class="token keyword">float</span> c <span class="token operator">=</span> <span class="token number">1.11</span><span class="token punctuation">,</span>d <span class="token operator">=</span> <span class="token number">2.22</span><span class="token punctuation">;</span> <span class="token function">Swap</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span>b<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">Swap</span><span class="token punctuation">(</span>c<span class="token punctuation">,</span>d<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>注意 typename 是用来定义模板参数的关键字,也可以使用 class (切记不要使用 struct 代替 class)。==这里可以看出函数模板类型一般是编译器根据显式传参将实参传给形参,推演出参数的类型==。</p><pre class="line-numbers language-c" data-language="c"><code class="language-c"><span class="token keyword">int</span> <span class="token function">Add</span><span class="token punctuation">(</span><span class="token keyword">int</span> a<span class="token punctuation">,</span><span class="token keyword">int</span> b<span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> a<span class="token operator">+</span>b<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token comment">//通用加法函数</span>template Add<span class="token operator">&lt;</span>class T<span class="token operator">&gt;</span>T <span class="token function">Add</span><span class="token punctuation">(</span>T a<span class="token punctuation">,</span>T b<span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> a<span class="token operator">+</span>b<span class="token punctuation">;</span><span class="token punctuation">}</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>你说咱这个模板函数他又像函数又不像函数,他是不是函数呢?只能说是但不完全是,普通函数是可以声明和定义分开的,而模板是不能这么玩儿的,这样分开会链接报错,一般会放到一个文件中或者有些地方命名成 xxx.hpp,寓意就是头文件和定义实现内容合并到一起。</p><h2 id="显示实例化指定🤔"><a href="#显示实例化指定🤔" class="headerlink" title="显示实例化指定🤔"></a>显示实例化指定🤔</h2><p>为什么模板分开就不通过呢?原因就是符号表里面找不到,我们还是要敏感编译链接的过程,我们执行代码时,==template.i 变成 template.s 编译完的时候就是空的,再变成 .o ,.exe 都是空的==。编译器对 template 是下不了手的。链接时没能去找到函数模板调用的地址,因为类型里面还有没确定的那就是模板里面的这个 T ,.cpp 文件里面只包含了 .h ,没有对 T 的定义那么模板就是一个空壳子。</p><p>解决这个尴尬的情况的方法有吗?有!但是非常 low,归根结底造成这种情况的罪魁祸首是谁?是咱自己,是我们没有给出他的定义,我们此时就能采用<font color="blue4" size="4">显示实例化指定:</font></p><font color="blue4" size="4"><pre class="line-numbers language-c" data-language="c"><code class="language-c">template<span class="token keyword">void</span> Swap<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token keyword">int</span><span class="token operator">&amp;</span> a<span class="token punctuation">,</span><span class="token keyword">int</span><span class="token operator">&amp;</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span>templateVector<span class="token operator">&lt;</span><span class="token keyword">int</span><span class="token operator">&gt;</span> v1<span class="token punctuation">;</span>Vector<span class="token operator">&lt;</span><span class="token keyword">double</span><span class="token operator">&gt;</span> v2<span class="token punctuation">;</span><span class="token comment">//整体实例化</span><span aria-hidden="true" class="line-numbers-rows"><span></span><span></span><span></span><span></span><span></span><span></span></span></code></pre><p>所以解决方案就有两个:一是在 template.cpp 里面针对于要使用费=的模板类型显示实例化,二就是在不要分离的两个文件中,直接写在 xxx.hpp 或者 xxx.h 里面。相比之下第一种方法十分的复杂,因为有一种类型就得实例化一种类型,所以我们更倾向于第二种方法。</p><p>简单的指令交给我们去写了,真正复杂的交给编译器去实现了,这里面不仅仅只有简单的交换类型,它比你想象的更复杂。</p><h2 id="类模板🤔"><a href="#类模板🤔" class="headerlink" title="类模板🤔"></a>类模板🤔</h2><p>我们C语言不是有 typedef 吗,也可以应对各种类型,为啥要搞模板呢?很简单,如果我定义了一个栈结构,非递归实现时我要让 st1 用来存 int,st2 用来存 double 这是没办法做到的,typedef 要改就要全部改,而且 typedef 很麻烦还要自己改。</p><p>于是我们加入了类模板,我们类模板没有传参这个过程, :</p><blockquote><p>template&lt;class T,class T2,……,class Tn&gt;<br>class<br>{<br> //成员定义<br>}</p></blockquote><p>在类模板外部定义成员函数的方法为:</p><blockquote><p>template&lt;模板形参列表&gt; 函数返回类型 类名&lt;模板形参名&gt;::函数名(参数列表){函数体}</p></blockquote><p> 比如定义一个==栈==的模板:</p><blockquote><p>template <class t=""><br>class Stack {<br>private:<br>vector<t> member; // 成员<br>public:<br>void push(T const&amp;); // 入栈<br>void pop(); //出栈<br>};<br>template <class t=""><br>void Stack<t>::push (T const&amp; a)<br>{<br>member.push_back(member);<br>} //定义域内 push 函数</t></class></t></class></p></blockquote><p>对于类模板,模板形参的类型必须在类名后的尖括号中明确指定。比如A&lt;2&gt; m;用这种方法把模板形参设置为int是错误的,类模板形参不存在实参推演的问题。也就是说不能把整型值2推演为int 型传递给模板形参。要把类模板形参调置为int 型必须这样指定A m。</p><p>说明一下本文是以C++初学者身份,所谓的深剖是相对初学者的深剖,不牵扯偏特化和继承。今天就到这里吧润了家人们。</p></font></font>]]></content>
<summary type="html">带你一命通关C++模板,十分钟手撕C++语法</summary>
<category term="C++" scheme="http://www.jojohome.cn/categories/C/"/>
<category term="模板" scheme="http://www.jojohome.cn/tags/%E6%A8%A1%E6%9D%BF/"/>
</entry>
<entry>
<title>手把手的 git 降伏指南——阿龙咸鱼经</title>
<link href="http://www.jojohome.cn/posts/511ca1ab.html"/>
<id>http://www.jojohome.cn/posts/511ca1ab.html</id>
<published>2022-07-01T14:06:16.714Z</published>
<updated>2022-07-02T04:49:08.001Z</updated>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>@<a href="%E7%9B%AE%E5%BD%95">TOC</a></p><h2 id="传统艺能😎"><a href="#传统艺能😎" class="headerlink" title="传统艺能😎"></a>传统艺能😎</h2><p>小编是双非本科大一菜鸟不赘述,欢迎大佬指点江山(QQ:1319365055)<br>此前博客<a href="https://blog.51cto.com/">点我!点我!请搜索博主 【知晓天空之蓝】</a></p><p>==🎉🎉非科班转码社区诚邀您入驻🎉🎉==<br>小伙伴们,打码路上一路向北,背后烟火,彼岸之前皆是疾苦<br>==一个人的单打独斗不如一群人的砥砺前行==<br>这是我和梦想合伙人组建的社区,诚邀各位有志之士的加入!!<br>社区用户好文均加精(“标兵”文章字数2000+加精,“达人”文章字数1500+加精)<br> 直达: <a href="https://bbs.csdn.net/forums/FKBZM?typeId=22226">社区链接点我</a></p><p> 🎉🎉🎉<font color="orange" size="5">倾力打造转码社区微信公众号🎉🎉🎉<br><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210382.png" alt="在这里插入图片描述"></font></p><font color="orange" size="5"><hr><p><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210128.png" alt="在这里插入图片描述"></p><h2 id="感受吧年轻人!🤔"><a href="#感受吧年轻人!🤔" class="headerlink" title="感受吧年轻人!🤔"></a>感受吧年轻人!🤔</h2><p>因为之前一直用的 TortoiseGit,所以没去接触 Git ,咱就是说用了以后还是俩字:真香,Git 确实好用所以欢喜来写个操作教程就当<br><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210210.png" alt="在这里插入图片描述"></p><p>随处可闻的 git 究竟有多重要?假如你是一个从茫茫人海脱颖而出的实习生苗子,来公司第一天老板丢给你分大文件叫你把里面代码 down 下来先看看,然而这时你连怎么去整合代码都不知道就无比尴尬了, git 其实已经是程序员自我修养的基础了,学会使用 git 未来进企业也会给前辈和同事减少不少麻烦工作,同事也为自己减负和加分。<br><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210320.png" alt="在这里插入图片描述"></p><h2 id="git-是啥🤔"><a href="#git-是啥🤔" class="headerlink" title="git 是啥🤔"></a>git 是啥🤔</h2><p>==用一句话概括:git是目前世界上最先进的分布式版本控制系统,没有之一!==</p><p>它是免费的,开源的分布式版本控制系统,可以高效的处理各种大小项目,他抑易于学习,占地小性能极快,有廉价的本地库。方便的暂存区和多个工作流分支。他的性能优于 Subversion,CVS 等版本控制工具。</p><h2 id="版本控制?🤔"><a href="#版本控制?🤔" class="headerlink" title="版本控制?🤔"></a>版本控制?🤔</h2><p>版本控制是一种记录文件内容变化一遍以便于查看特定历史版本修订情况的系统,他最大特点就是可以修改历史记录方便版本切换。</p><p>比如你负责维护一款 APP 的某个功能,而某一天他突然出现一个重大错误需要 hot fix ,这时又正好是用户使用的高峰期,怎么办呢?救星就是我们的 git ,他会从面对用户上的版本做一个 branch 分支,我们对这个分支进行修改,完事儿直接合并回去就行。这样麻烦也解决了又不产生业务损失。这就是神一般的版本控制系统。</p><h2 id="git-安装🤔"><a href="#git-安装🤔" class="headerlink" title="git 安装🤔"></a>git 安装🤔</h2><p><a href="https://git-scm.com/">官网链接</a></p><p>进入官网再根据自己配置进行下载即可们,但是由于官网下载速度过于缓慢,而且我还下载报错: 无法下载,需要某网站授权。</p><p><font color="blue4" size="4">推荐在git下载的某宝镜像网站下下载,最新版本在网页下面,请各取所需:</font></p><font color="blue4" size="4"><p><a href="https://registry.npmmirror.com/binary.html?path=git-for-windows/">镜像网站下载链接</a></p><p><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210621.png" alt="在这里插入图片描述"></p><h2 id="分布式-vs-集中式🤔"><a href="#分布式-vs-集中式🤔" class="headerlink" title="分布式 vs 集中式🤔"></a>分布式 vs 集中式🤔</h2><p>为什么是分布式而不是集中式呢?很简单,假如一个项目有多个人来完成,集中式有一个集中管理的服务器,保存所有文件的修订版本,每个成员能看到各自的进度,管理员也轻松掌握每个成员的权限,而且管理一个集中化的系统远比在各个客户端上进行维护要轻松许多。</p><p><font color="orange" size="3">但是吧如果机器宕掉了或者坏掉了,无法提交更新也无法协同工作,那么就面临着全体干瞪眼儿的尴尬,所以这种架构有一个致命缺点就是他的中央服务器的单点故障。</font></p><font color="orange" size="3"><p>所以这时以 git 为代表的版本控制工具就来了,==他并不是文件快照,而是把代码仓库完整的镜像拷贝下来,每一次文件客户端的文件提取操作都是一次对整个文件仓库的完整备份==。他不仅实现了不受断网环境影响的开发,还更加安全。</p><h2 id="工作机制🤔"><a href="#工作机制🤔" class="headerlink" title="工作机制🤔"></a>工作机制🤔</h2><p>憋看咱 git 功能强大,其实底层工作机制很简单。</p><p>==git 大概分为三个部分,工作区,暂存区和本地库==。工作区指的是代码存放的磁盘目录的位置;暂存区是写完代码后,git 去追踪这个代码,其实就是让 git 知道咱有这么个代码,所以需要将工作区代码添加到暂存区;最后提交到本地库就会生成对应的历史版本,一旦生成他就是你抹不去的印记了(远程库)!<br><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210215.png" alt="在这里插入图片描述"><br>远程库就是所谓的代码托管中心,耳熟能详的 Github , Gitee,这些是互联网托管中心,还有局域网托管中心比如 GitLab。</p><h2 id="Git-常用命令🤔"><a href="#Git-常用命令🤔" class="headerlink" title="Git 常用命令🤔"></a>Git 常用命令🤔</h2><p>因为 git 开发者是林纳斯,也就是 Linux 之父,所以命令也是承袭了 Linux 的指令,Linux我们都很容易上手,但是没接敢说自己精通 Linux 指令的,git 也是同理所以我只列出重点常用的。</p><p>命令哪里输入?你只需要戍边右键点开找到 git bash ,打开是像这样一个框框(初始是没有代码的,这时我截的我当前的)<br><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210873.png" alt="在这里插入图片描述"></p><h3 id="设置用户签名🎉"><a href="#设置用户签名🎉" class="headerlink" title="设置用户签名🎉"></a>设置用户签名🎉</h3><pre class="line-numbers language-c" data-language="c"><code class="language-c">git config <span class="token operator">--</span>global user<span class="token punctuation">.</span>name 用户名git config <span class="token operator">--</span>global user<span class="token punctuation">.</span>email 邮箱<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>从咱安装好那一刻开始,只需要设置这一次用户签名就够了,如果没设置将来提交代码时是会报错的,签名的作用是区分不同操作者的身份,用户的签名信息在每一次提交信息中都可以看到。</p><h3 id="初始化本地库🎉"><a href="#初始化本地库🎉" class="headerlink" title="初始化本地库🎉"></a>初始化本地库🎉</h3><pre class="line-numbers language-c" data-language="c"><code class="language-c">git init<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>==我们要让 git 来管理一个目录时,那就必须要让 git 获得该目录的管理权==。我以我自己的本地库为例,我在 D 盘创建了一个名为 yunying 的文件夹,我想让当前文件夹成为我的本地库,那我就直接进入该文件夹,右键唤出 git bash ,输入 git init 就会创建出一个 master 分支(默认分支名为 master),分支当前无操作所以 ll 指令查看分支内容为 0。</p><p><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210388.png" alt="在这里插入图片描述"></p><h3 id="本地库状态查看🎉"><a href="#本地库状态查看🎉" class="headerlink" title="本地库状态查看🎉"></a>本地库状态查看🎉</h3><pre class="line-numbers language-c" data-language="c"><code class="language-c">git status<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>status 即状态,这个命令可查看当前库的状态<br><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210071.png" alt="在这里插入图片描述"><br>一但有个风吹草动比如创建了一个 hello.txt ,再使用 vim 编辑一下就会变成 “红码”, 就是因为我们做出来编辑动作,而对于他 git 还从来没追踪过,说明这个文件还在工作区。<br><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210575.png" alt="在这里插入图片描述"></p><h3 id="添加暂存区🎉"><a href="#添加暂存区🎉" class="headerlink" title="添加暂存区🎉"></a>添加暂存区🎉</h3><p>要将文件从工作区添加到暂存区就要用 add 命令:</p><pre class="line-numbers language-c" data-language="c"><code class="language-c">git add 文件名<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>添加完了他会显示两行警告:<br><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210477.png" alt="在这里插入图片描述"></p><p>这个警告的出现其实就是添加成功了,==它是提醒你一下 git 帮你默认转换了一下行末换行符==,就是把 Windows 环境下的 CRLF 替换为 Linux 中的 LF。并没有什么实际作用(和某局警告一样)</p><p><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210506.png" alt="在这里插入图片描述"></p><p>那么添加完了我们 git status 查看状态他的日志信息就会改变,红码变绿码:</p><p><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210987.png" alt="在这里插入图片描述"><br>这里面也告诉我们如何删除这个文件也就是这行:</p><pre class="line-numbers language-c" data-language="c"><code class="language-c">git rm <span class="token operator">--</span>cached 文件名<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p><font color="blue4" size="4">这个所谓的删除实质上是把暂存区的删掉而工作区的不会被连坐。</font></p><font color="blue4" size="4"><h3 id="提交本地库🎉"><a href="#提交本地库🎉" class="headerlink" title="提交本地库🎉"></a>提交本地库🎉</h3><p>这一步就是将暂存区文件提交到本地库,形成一个历史版本:</p><pre class="line-numbers language-c" data-language="c"><code class="language-c">git commit <span class="token operator">-</span>m <span class="token string">"日志信息"</span> 文件名<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>这个 -m 的作用是去写跟在他后面的一个日志信息,如果没有 -m 操作,在提交时 git 也会弹出一个提示框叫你添加,不然没法提交。提交成功后就是这样一个样子:<br><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210064.png" alt="在这里插入图片描述"><br>日志信 first commit 前面跟了一串数字:965c6a1,这就是提交的版本号,看到他就证明咱提交成功了。</p><h3 id="查看日志信息🎉"><a href="#查看日志信息🎉" class="headerlink" title="查看日志信息🎉"></a>查看日志信息🎉</h3><p>那完事儿了我们咋查看历史版本信息呢?我们可以用 reflog (reference logs,即参考日志)<br>和 log</p><pre class="line-numbers language-c" data-language="c"><code class="language-c">git refloggit log<span aria-hidden="true" class="line-numbers-rows"><span></span><span></span></span></code></pre><p>他俩都可以查看历史版本信息,但是 log 是查看详细版本日志信息,包括用户签名,提交时间以及完整的版本号:<br><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210147.png" alt="在这里插入图片描述"><br><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210346.png" alt="在这里插入图片描述"><br><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210415.webp" alt="在这里插入图片描述"></p><h3 id="修改文件🎉"><a href="#修改文件🎉" class="headerlink" title="修改文件🎉"></a>修改文件🎉</h3><p>如果我要对当前在暂存区中的文件进行修改,假如我 vim hello.txt ,在里面增加了几行代码,回来查看当前本地库状态就会变成这样:</p><p><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210804.png" alt="在这里插入图片描述"></p><p>这行红字 modified 就证明我们已经对 hello.txt 进行了修改操作,而且这次修改导致了文件不能被追踪到,掉出了暂存区,只需要再来一次 add 和 commit 即可,但是提交后的就是第二次版本信息了。</p><h3 id="版本穿梭🎉"><a href="#版本穿梭🎉" class="headerlink" title="版本穿梭🎉"></a>版本穿梭🎉</h3><pre class="line-numbers language-c" data-language="c"><code class="language-c">git reset <span class="token operator">--</span>hard 版本号<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>既然我们有了历史版本,那么总有一天会像回到曾经那个版本,去对比去品鉴去驻足,就好像咱男人想回到曾经的某个过去</p><p><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210776.jpeg" alt="在这里插入图片描述"><br>我们想跑到哪扇门就得先知道门牌号,直接 reflog 查看一手之前的各个版本号:<br><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210899.png" alt="在这里插入图片描述"><br>比如 e88c8a5 就对应一个头指针指向 master 分支,如果想跳到 second commit 这个二号版本,直接复制前面的版本号 e88c8a5 ,用 reset 命令就行,执行完后再次查看日志就会发现头指针已经指向了 master 分支:<br><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210745.png" alt="在这里插入图片描述"><br><font color="blue4" size="4">原理:</font></p><font color="blue4" size="4"><p>假如有一个 version 版本,有一个 master 分支,那这个 master 分支一定指向 version 这个版本,git 会有一个 head 头指针指向这个分支,整体上 head 指向 master 这个躯干是不会动的,只需调整 master 的走向即可。</p><h3 id="分支操作🎉"><a href="#分支操作🎉" class="headerlink" title="分支操作🎉"></a>分支操作🎉</h3><p>当下一个生产链上的分支结构大概就长这样:<br><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210560.png" alt="在这里插入图片描述"><br>版本控制中同时推进多个任务,每个任务我们可以创建其单独的分支,这就意味着我们可以将自己的工作从偌大的主线上抠出来,开发同时不影响主线分支运行。</p><p>git 中关于分支的操作并不是很多,所以不需要我们去劳神费力的记:<br><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210572.png" alt="在这里插入图片描述"></p><h3 id="分支的正常合并🎉"><a href="#分支的正常合并🎉" class="headerlink" title="分支的正常合并🎉"></a>分支的正常合并🎉</h3><p>如果我现在有两条分支 master 和 new ,如果我想把 new 分支合并到 master 分支上,就要 checkout 切换分支到 master 上,让 master 站在当前分支的角度进行合并,==对 new 分支不会有影响==:</p><pre class="line-numbers language-c" data-language="c"><code class="language-c">git mrege new<span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210812.png" alt="在这里插入图片描述"></p><p>这就是合并成功的样子,合并分支的底层原理依然是指针,和切换分支同理。</p><h3 id="分支的冲突合并🎉"><a href="#分支的冲突合并🎉" class="headerlink" title="分支的冲突合并🎉"></a>分支的冲突合并🎉</h3><p>为什么会有冲突合并呢?==因为合并分支时,两个分支在同一个文件的同一个位置有两套完全不同的修改, git 只是一个合并的工具他没办法替我们决定使用哪一个,所以必须进行人为指定==。</p><p>比如我原始版本里面内容是 123,master 分支下我修改为 123 -4,hot-fix 分支下我修改为 123 +5。我切换到 master 分支,执行 merge hot-fix,这时的日志就会大不一样了:</p><p><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210888.png" alt="在这里插入图片描述"><br> 这里报了一个自动合并失败的冲突,这就说明他并没有合并成功,需要我们手动搞定他,我们 vim 打开文件,这时 git 已经把不同点给我们写出来,我们只需要留下我们需要的,删除多余的包括系统用来标注不同点的符号(&lt; , = 和 &gt;),然后保存退出即可。<br> <img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210079.png" alt="在这里插入图片描述"><br>此时本地库状态依然是红色的,而且是 both modified,此时像原来一样进行 commit 是不行的,合并对象他依然无法决定,所以我们要强调一下merge 后提交不能带文件名,直接执行下列指令即可 :</p><pre class="line-numbers language-c" data-language="c"><code class="language-c">git commit <span class="token operator">-</span>m “日志信息” <span aria-hidden="true" class="line-numbers-rows"><span></span></span></code></pre><p>报错信息:<br><img src="https://taffy2.oss-cn-chengdu.aliyuncs.com/image/202207012210734.png" alt="在这里插入图片描述"><br>今天就到这里吧,润了家人们。</p></font></font></font></font></font>]]></content>
<summary type="html">带你一命通关 git ,分分钟玩转 git,上手极香系列</summary>
<category term="工具" scheme="http://www.jojohome.cn/categories/%E5%B7%A5%E5%85%B7/"/>
<category term="git" scheme="http://www.jojohome.cn/tags/git/"/>
</entry>
</feed>
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化