﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-我的编程乐园</title><link>http://www.cppblog.com/deercoder/</link><description>&lt;P&gt;&lt;FONT style="FONT-SIZE: 20px" color=#ff0000&gt;积累，坚持！&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT style="FONT-SIZE: 20px" color=#ff0000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ---------我是一只IT小小鸟&lt;/FONT&gt;&lt;/P&gt;</description><language>zh-cn</language><lastBuildDate>Thu, 23 Apr 2026 10:07:40 GMT</lastBuildDate><pubDate>Thu, 23 Apr 2026 10:07:40 GMT</pubDate><ttl>60</ttl><item><title>此博客停止更新</title><link>http://www.cppblog.com/deercoder/archive/2014/12/14/209182.html</link><dc:creator>deercoder</dc:creator><author>deercoder</author><pubDate>Sun, 14 Dec 2014 05:56:00 GMT</pubDate><guid>http://www.cppblog.com/deercoder/archive/2014/12/14/209182.html</guid><wfw:comment>http://www.cppblog.com/deercoder/comments/209182.html</wfw:comment><comments>http://www.cppblog.com/deercoder/archive/2014/12/14/209182.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/deercoder/comments/commentRss/209182.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/deercoder/services/trackbacks/209182.html</trackback:ping><description><![CDATA[一直以来，此博客都是本人用于记录学习心得和技术笔记的一个地方，大学的时候开始笔耕不辍，留下了自己不少宝贵的回忆，也记录自己的青春。工作后，由于工作内容的限制，技术分享很少，而且个人亦疏于管理，所以已成荒废趋势。<br /><br />目前，本人在美帝求学，专研大数据和深度学习，移动互联网及应用，考虑到研究和个人提升的需要开通了Google website和google blogger用于写作，以历练英语。本人一直崇尚互联网分享和开源软件精神，亦准备后续在自己的能力范围内为互联网普及和开源软件的开发和推广做贡献，考虑到目前此博客已不再适合自己的写作，故转战其他地址，望各位看客见谅。<br /><br />另外，希望看客不要再留下任何人身攻击的评论，于人于己都无益处，本人写作纵使漏洞百出亦非强迫你领会接受，只作为个人存档使用而已，一个对技术有热爱的人应该是有探究精神来判断正误，而非拿来主义或者动辄破口大骂，我也没有时间去清理这些难等大雅之堂的评论，望理解见谅。<br /><br />Dec 14th, 12:54 am @MA<img src ="http://www.cppblog.com/deercoder/aggbug/209182.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/deercoder/" target="_blank">deercoder</a> 2014-12-14 13:56 <a href="http://www.cppblog.com/deercoder/archive/2014/12/14/209182.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Adboe Reader提示中文字体有问题</title><link>http://www.cppblog.com/deercoder/archive/2013/03/10/198330.html</link><dc:creator>deercoder</dc:creator><author>deercoder</author><pubDate>Sun, 10 Mar 2013 04:30:00 GMT</pubDate><guid>http://www.cppblog.com/deercoder/archive/2013/03/10/198330.html</guid><wfw:comment>http://www.cppblog.com/deercoder/comments/198330.html</wfw:comment><comments>http://www.cppblog.com/deercoder/archive/2013/03/10/198330.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/deercoder/comments/commentRss/198330.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/deercoder/services/trackbacks/198330.html</trackback:ping><description><![CDATA[<h1>Adobe Reader提示中文字体缺失</h1>
<p>正常使用情况下，没有任何问题，环境是：</p>
<p>OS: Ubuntu 10.04</p>
<p>Version: Aodbe Reader 9.5.1</p>
<p>但是打开部分文档，可能是LateX生成的文档时，出现问题，由于字体不完全导致。</p>
<p>解决办法：</p>
<p>下载：</p>
<pre><code> http://ardownload.adobe.com/pub/adobe/reader/unix/9.x/9.1/misc/FontPack910_chs_i486-linux.tar.bz2
</code></pre>
<p>然后以管理员身份运行，即可。</p>
<p><strong> 此安装包解决了字体的问题，不仅仅针对于 Adobe Reader软件，使用默认的阅读器会发现也能够正常浏览文档了，所以对于字体是普遍生效的。</strong></p>
<img src ="http://www.cppblog.com/deercoder/aggbug/198330.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/deercoder/" target="_blank">deercoder</a> 2013-03-10 12:30 <a href="http://www.cppblog.com/deercoder/archive/2013/03/10/198330.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python字符串换行处理</title><link>http://www.cppblog.com/deercoder/archive/2012/07/08/182137.html</link><dc:creator>deercoder</dc:creator><author>deercoder</author><pubDate>Sat, 07 Jul 2012 16:52:00 GMT</pubDate><guid>http://www.cppblog.com/deercoder/archive/2012/07/08/182137.html</guid><wfw:comment>http://www.cppblog.com/deercoder/comments/182137.html</wfw:comment><comments>http://www.cppblog.com/deercoder/archive/2012/07/08/182137.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/deercoder/comments/commentRss/182137.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/deercoder/services/trackbacks/182137.html</trackback:ping><description><![CDATA[最近看了一点点Python的东西，感觉这门语言非常强大，已经到了令人发指的程度，结果是，想要实现的很多功能都可以用极为简单的几句代码实现，难怪这么语言这么有生命力。至于说它让人变的更笨，让人脱离底层处理，忽视了基本的硬件了解这种指责，或者说它让程序员的工作和生活更加便利等争论，我也没有多大的兴趣去了解，语言只是工具，为我所用而已。<br /><br />虽然了解不多，不过感觉处理文件和字符串非常强大，因此就有一个需求，希望将网上copy的连续的单词组成的字符串按照空格分割开来，并重新写入到文件中，这样文件的每一行都是一个单词，而且后面还可以加入注释。由于手动换行非常麻烦，所以希望用python来实现这个简单的小功能。<br />具体实现代码如下，确实非常简单：<br /><div class="vimiumReset vimiumHUD" style="right: 150px; opacity: 0; display: none; "></div><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; "><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000; ">#</span><span style="color: #008000; ">!&nbsp;/usr/bin/python</span><span style="color: #008000; "><br />#</span><span style="color: #008000; ">Description:&nbsp;read&nbsp;file&nbsp;and&nbsp;arrange&nbsp;them&nbsp;in&nbsp;lines&nbsp;by&nbsp;words</span><span style="color: #008000; "><br /></span><br />file&nbsp;=&nbsp;open(<span style="color: #800000; ">"</span><span style="color: #800000; ">test</span><span style="color: #800000; ">"</span>,&nbsp;<span style="color: #800000; ">"</span><span style="color: #800000; ">r</span><span style="color: #800000; ">"</span>)<br />str&nbsp;=&nbsp;file.read()<br />tup&nbsp;=&nbsp;str.split(<span style="color: #800000; ">"</span><span style="color: #800000; ">&nbsp;</span><span style="color: #800000; ">"</span>)<br />writeStr&nbsp;=&nbsp;<span style="color: #800000; ">""</span><br /><span style="color: #0000FF; ">for</span>&nbsp;i&nbsp;<span style="color: #0000FF; ">in</span>&nbsp;tup:<br />&nbsp;&nbsp;&nbsp;&nbsp;writeStr&nbsp;+=&nbsp;i&nbsp;+&nbsp;<span style="color: #800000; ">"</span><span style="color: #800000; ">\n</span><span style="color: #800000; ">"</span><br />outfile&nbsp;=&nbsp;open(<span style="color: #800000; ">"</span><span style="color: #800000; ">out</span><span style="color: #800000; ">"</span>,&nbsp;<span style="color: #800000; ">"</span><span style="color: #800000; ">w</span><span style="color: #800000; ">"</span>)<br />outfile.write(writeStr)<br /><span style="color: #0000FF; ">print</span>&nbsp;tup</div><br />确实非常简单，最后也实现了想要的效果。后续需要想办法加入查询的过哦你你，即对每一行的这个单词，想办法查询它的意思，然后一起写进去，这样，copy的这个连串的字符串就能够得到每一个单词的释义了。<br /><br />另外，VIM有一个很好的功能，使用J，在命令模式下可以连接成一行，因此文件开始的时候是：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all">&nbsp;### filename: out<br />impart<br />apotheosis<br />pulp<br />nobility<br />reimburse<br />flora<br />deliberately<br />twine<br />heresy<br />effluent<br />condone<br />flout<br />sermon<br />concur<br />elation<br />slab<br />aerate<br />backdrop<br />emblem<br />chicanery<br />disqualify<br />hypersensitive<br />fitful<br />coil<br />irresolute<br />contemptible<br />hinge<br />tectonics<br />bicker<br />tilted<br />collaborate<br />salutary<br />annul<br />vex<br />maxim<br />scanty<br />reptile<br />transfix<br />impending<br />intersect<br />drill<br />inviting<br />retreat<br />serrated</div><br />经过VIM处理之后就变成了一行：<br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->### filename: test ####<br />impart&nbsp;apotheosis&nbsp;pulp&nbsp;nobility&nbsp;reimburse&nbsp;flora&nbsp;deliberately&nbsp;twine&nbsp;heresy&nbsp;effluent&nbsp;condone&nbsp;flout&nbsp;sermon&nbsp;concur&nbsp;elation&nbsp;slab&nbsp;aerate&nbsp;backdrop&nbsp;emblem&nbsp;chicanery&nbsp;disqualify&nbsp;hypersensitive&nbsp;fitful&nbsp;coil&nbsp;irresolute&nbsp;contemptible&nbsp;hinge&nbsp;tectonics&nbsp;bicker&nbsp;tilted&nbsp;collaborate&nbsp;salutary&nbsp;annul&nbsp;vex&nbsp;maxim&nbsp;scanty&nbsp;reptile&nbsp;transfix&nbsp;impending&nbsp;intersect&nbsp;drill&nbsp;inviting&nbsp;retreat&nbsp;serrated</div><br />然后在把这个文件作为输入，经过程序重新写回去，就成为了第一个上面所示的单词，现在在思考哪些地方可以抓取这些单词呢？貌似Google翻译已经没有API支持了，不知道哪位大侠可以给于指导？<img src ="http://www.cppblog.com/deercoder/aggbug/182137.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/deercoder/" target="_blank">deercoder</a> 2012-07-08 00:52 <a href="http://www.cppblog.com/deercoder/archive/2012/07/08/182137.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何转换^M行末符号</title><link>http://www.cppblog.com/deercoder/archive/2012/07/07/182123.html</link><dc:creator>deercoder</dc:creator><author>deercoder</author><pubDate>Sat, 07 Jul 2012 14:54:00 GMT</pubDate><guid>http://www.cppblog.com/deercoder/archive/2012/07/07/182123.html</guid><wfw:comment>http://www.cppblog.com/deercoder/comments/182123.html</wfw:comment><comments>http://www.cppblog.com/deercoder/archive/2012/07/07/182123.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/deercoder/comments/commentRss/182123.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/deercoder/services/trackbacks/182123.html</trackback:ping><description><![CDATA[Windows和Linux下面对于行末符的表示不同，Windows下面是\r\n，而Linux则是\n<br />因此，如果在Windows下面编辑的脚本文件，如shell脚本文件，在Linux下面执行失败，会提示多一个^M符号，用VIM打开也会发现增加这个符号。<br /><br />解决办法：<br />1. 用VIM打开，设置编码为unix<br />：set fileformat=unix<br />然后，保存，结尾unix格式。<br /><br />2. 使用VIM的替换功能，替换行末的\r符号即可<br /><span style="color: #444444; font-family: Tahoma, Helvetica, SimSun, sans-serif, Hei; background-color: #ffffff; ">:%s/^M//g<br /><br /></span>3. 使用sed来进行批量处理<br /><span style="font-family: Arial, Helvetica, sans-serif, 瀹嬩綋; line-height: 24px; background-color: #fcf1f5; ">&nbsp;sed &#8217;s/^M//&#8217; filename &gt; tmp_filename</span><br /><br />4. 批量处理（推荐使用）<br />sudo apt-get install dos2unix<br />find . * | xargs dos2unix （对当前目录下面的所有文件执行转换格式的命令）<br /><br />一个需要注意的点：dos2unix需要root权限，我开始的时候没有用sudo运行，提示转换失败，后来利用sudo执行即可。<br />问题的根源来源于：<br />在Windows下面拉取Git上面的代码，结果给版本库所有的文件都加上了行末符号，而在Linux下面再次编辑该文件就发现所有的问题都出现问题，提交的时候又不能<br />把所有的文件都提交成Windows的编码，因为这部分修改是没有意义的，所以需要批量转换。<br /><br /><span style="font-family: Arial, Helvetica, sans-serif, 瀹嬩綋; line-height: 24px; background-color: #fcf1f5; "><br /></span><div class="vimiumHUD" style="right: 150px; opacity: 0; display: none; "></div><div class="vimiumReset vimiumHUD" style="right: 150px; opacity: 0; display: none; "></div><img src ="http://www.cppblog.com/deercoder/aggbug/182123.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/deercoder/" target="_blank">deercoder</a> 2012-07-07 22:54 <a href="http://www.cppblog.com/deercoder/archive/2012/07/07/182123.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>斯坦福大学开放课程--编程范式（四）</title><link>http://www.cppblog.com/deercoder/archive/2012/06/24/180038.html</link><dc:creator>deercoder</dc:creator><author>deercoder</author><pubDate>Sun, 24 Jun 2012 08:57:00 GMT</pubDate><guid>http://www.cppblog.com/deercoder/archive/2012/06/24/180038.html</guid><wfw:comment>http://www.cppblog.com/deercoder/comments/180038.html</wfw:comment><comments>http://www.cppblog.com/deercoder/archive/2012/06/24/180038.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/deercoder/comments/commentRss/180038.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/deercoder/services/trackbacks/180038.html</trackback:ping><description><![CDATA[<p style="margin-top: 18px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; "><span style="font-size: x-large; font-weight: 600; "></span></p><p style="margin-top: 18px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; "><span style="font-size: x-large; font-weight: 600; ">综述</span></p> <p style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">本节课的主要内容是关于泛型数据的拷贝，虽然是使用C语言实现，并且没有用到C++中的模板这种泛型编程技术，但是效果却非常好。本节内容紧接上节所将的字节位拷贝的知识，充分利用了字节拷贝技术。</p> <p style="margin-top: 16px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; "><span style=" font-size:x-large; font-weight:600;">笔记</span></p> <p style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">由于内容和例子不断深入，实际核心内容则比较集中，因此这里只进行总结讨论。</p> <p style="margin-top: 16px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; "><span style=" font-size:x-large; font-weight:600;">引例</span></p> <p style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">本节所有的例子都是针对于数据交换来进行的，从最简单的例子开始，不断深入。 开始是关于一个最简单的整数数据的交换实例：</p> <pre style="margin-top: 12px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">void swap(int a, int b){</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">        int tmp = a;</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">        a = b;</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">        b = tmp;</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">}</span></pre> <pre style="margin-top: 0px; margin-bottom: 12px; font-family: 'Courier New,courier'; "></pre> <p style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">此例子非常简单，只需要构造一个简单的中间临时变量tmp用来存放a的值，并且交换赋值相关的数据，就可以达到交换的目的。</p> <p style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">但是，此实例有一个缺陷，就是值传递，而不是引用传递，这样，传递的值虽然改变，但是只想原始变量的单元却没有改变，具体来说就是：</p> <pre style="margin-top: 12px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">a = 23;</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">b = 34</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">swap(a, b);</span></pre> <pre style="margin-top: 0px; margin-bottom: 12px; font-family: 'Courier New,courier'; "></pre> <p style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">执行上面一段语句会发现，其实a，b的值并没有交换，原因和C/C++的参数的值传递以及指针传递有关系。函数调用的时候，只会拷贝a，b的值，因此调用swap的时候，交换的是形参，实际参数的值并没有改变。</p> <p style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">要实现真正参数传递的效果，需要用指针的形式来实现：</p> <pre style="margin-top: 12px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">void swap(int *vp1, int *vp2) {</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">    int a = *vp1;</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">    *vp1 = *vp2;</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">    *vp2 = *vp1;</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">}</span></pre> <pre style="margin-top: 0px; margin-bottom: 12px; font-family: 'Courier New,courier'; "></pre> <p style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">再次调用swap(&amp;a, &amp;b)的时候，就会修改掉原来的值，因为这里传递过去的就是指针，所以，对<span style=" font-style:italic;">vp1，</span>vp2的操作 就是对指向单元a，b的操作，所以能够修改对应的值。</p> <p style="margin-top: 16px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; "><span style=" font-size:x-large; font-weight:600;">泛型交换与拷贝</span></p> <p style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">上面的例子，只是对某种特定的类型进行交换，比如int类型，如果想对double类型等进行交换，只需要修改其类型为double即可，其他类型类似。 但是考虑到需要对多种不同类型进行交换，是否存在一种通用的方法呢？ 在C++中，可以用模板template技术，然而这里，回想起上节课中讲到的字节操作，能否利用字节的拷贝来实现呢？答案是肯定的。</p> <pre style="margin-top: 12px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">void swap(void *vp1, void *vp2, int size){</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">    char buffer[size];</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">    memcpy(buffer, vp1, size);</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">    memcpy(vp1, vp2, size);</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">    memcpy(vp2, buffer, size);</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">}</span></pre> <pre style="margin-top: 0px; margin-bottom: 12px; font-family: 'Courier New,courier'; "></pre> <p style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">调用的时候，字号需要给定某个类型，即可实现。比如，通过：</p> <pre style="margin-top: 12px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">double a = 23.0, b = 34.0;</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">swap(&amp;a, &amp;b, sizeof(double));</span></pre> <pre style="margin-top: 0px; margin-bottom: 12px; font-family: 'Courier New,courier'; "></pre> <p style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">当然，对于结构体也可以通过这种形式来进行拷贝。</p> <p style="margin-top: 14px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; "><span style=" font-size:large; font-weight:600;">关于上面例子的几点说明：</span></p> <ol style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style="margin-top: 12px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; ">这里声明数组的方式，使用的大小size是可变的，这只在某些编译器中支持，这里只是为了说明字符拷贝的方式，例子的重点在于交换。当然可以使用malloc或者new来动态分配大小可变的空间。</li> <li style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; ">这里使用memcpy(dest, src, size)这个函数来进行内存单元的拷贝，注意此函数并不关心你的数据类型，单纯的进行单元的拷贝而已，所以虽然编译可能通过，但是还需要自己进行判断和控制。</li> <li style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; ">这个例子的亮点就在于void*的使用，通过它能够实现泛型，即针对于int，short，char，struct等类型都能够保证能够拷贝交换成功。</li> <li style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; ">template和这里的区别和优缺点。注意到使用模板的话，编译后，会为每种类型都生成一种代码，比如int对应的，float对应的，这样如果调用次数很多的话，代码体积会增大，冗余过多。而这里编译出来就一套代码，更加简洁。</li> <li style="margin-top: 0px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">这里传递一个参数大小size是因为，由于泛型指针void*的存在，所以编译器并不知道要拷贝多少个字节，所以，需要你手动控制并指定一个大小。</li></ol> <p style="margin-top: 14px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; "><span style=" font-size:large; font-weight:600;">存在的问题</span></p> <p style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">由于编译器会很容易的放过void*带来的错误，所以如果两个类型不同的数据调用此函数，就会出现问题：</p> <pre style="margin-top: 12px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">    double a = 23.0;</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">    int b = 345;</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">    swap(&amp;a, &amp;b, sizeof(double));</span></pre> <pre style="margin-top: 0px; margin-bottom: 12px; font-family: 'Courier New,courier'; "></pre> <p style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">这里，double和int类型占据的数据空间的大小是不同的，因此，如果单纯的直接调用这个函数，就会出错，简单的结果就是，截断拷贝或者多拷贝数据。 比如，int类型拷贝到double数据空间的时候，只有前面2个字节拷贝了，后面的原来double数据的两个字节仍然保留了；或者说double拷贝到int的时候，可能会多拷贝两个字节到int后面的数据，造成出错。具体的方式，与后面一个参数sizeof(double)或者sizeof(int)有关系。</p> <p style="margin-top: 14px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; "><span style=" font-size:large; font-weight:600;">初学者容易犯的错误</span></p> <ol style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">使用void * tmp = vp1，而不是前面锁讲到的char buffer[size]，这个错误的原因是由于不理解void不是一个类型，不像int，double等属于一个类型，所以错误。void <span style=" font-style:italic;">只能用作函数参数，返回值才可行。但是可以使用 void * tmp = (int </span>)&amp;a这类的用法，因为具体的类型即可以赋值给一般的类型，你只有给定了一个具体的类型，才能让编译器知道规则，才能编译通过。</li> <li style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">指针的拷贝，何时使用引用地址的问题。一个简单的例子出发，</li></ol> <p style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">char * husband = strdup("Fred"); char * wife = strdup("Wilma");</p> <p style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">如果想交换两人所指向的空间内容，正确的做法是：</p> <pre style="margin-top: 12px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">swap(&amp;hustband, &amp;wife, sizeof(char *))</span></pre> <pre style="margin-top: 0px; margin-bottom: 12px; font-family: 'Courier New,courier'; "></pre> <p style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">也就是说，这里要交换的是指针的地址，交换之后，husband的内容发生了变化，内容变成了原来wife的内容，由于本身是地址，所以内容变了，实际上所只想的地址也变了，现在husband指向原来wife所指向的地址，而wife指向原来husband指向的地址。</p> <p style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">一个错误的例子就是，swap(husband, wife, &amp;sizeof(char <span style=" font-family:'Courier New,courier';">*</span>))，这样，交换的实际上是他们锁指向的内容，即存放Fred和Wilama的单元中的内容会交换，而且，由于char <span style=" font-family:'Courier New,courier';">*</span>是四个字节，因此交换的就只有四个字节的内容。 为何会如此呢？因为上面的例子，比如要交换a，b单元的内容，传入的就是a，b的地址&amp;a, &amp;b，同样，这里我直接传入指针，当然交换的是他们指向的单元的内容，即两个字符串。 所以要交换两个指针的内容，就要交换他们的地址，即指针的地址，指针的指针。</p> <p style="margin-top: 16px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; "><span style=" font-size:x-large; font-weight:600;">另外一个例子</span></p> <p style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">思考一个下面线性搜索的例子，</p> <pre style="margin-top: 12px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">int * lsearch(int key ,int* array, int size){</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">    for (int i = 0; i &lt; size; i++)  </span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">    {</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">        if(array[i] == key)</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">            return i;</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">    }</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">}</span></pre> <pre style="margin-top: 0px; margin-bottom: 12px; font-family: 'Courier New,courier'; "></pre> <p style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">上面的这段代码，直接返回的就是找到索引的那个下标。</p> <p style="margin-top: 14px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; "><span style=" font-size:large; font-weight:600;">利用位比较的方式来实现</span></p> <p style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">同样，为了应用上面我们学到的知识，这里想要泛型比较，搜索，如何实现？ 例如，对于这里的int，能否用一个struct，一个double或者其他类型。 答案仍然是肯定的，只不过，我们需要对其中编译器的工作，比较的大小进行控制而已。</p> <pre style="margin-top: 12px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">int *lsearch(void *key, void *base, int size, int elementSize){</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">    for (int i = 0; i &lt; size; i++) {</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">      void * elemeAddr = (char *)base + i * elementSize; </span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">      if (memcmp(key, elemeAddr, elementSize) == 0)</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">        return elemeAddr;</span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">    }       </span></pre> <pre style="margin-top: 0px; margin-bottom: 0px; "><span style=" font-family:'Courier New,courier';">}</span></pre> <pre style="margin-top: 0px; margin-bottom: 12px; font-family: 'Courier New,courier'; "></pre> <p style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; ">这里的几个说明点就是，首先，传入参数的size就是要比较的数组的大小，类型我们不知道，就用void *类型，然后要传入每一个类型的大小，elementSize，这个标记了每一个数组成员的大小，正因为有这个我们才可以精准的定位到具体的单元，利用for循环来比较每一个单元和key的关系。而这里比较用的memcmp来进行，比较的字节数就是elementSize，传入两个指针即可，而比较的指针就是数组的每一个单元的地址，即elemeAddr而已。<br /><br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;---Written by markdown and HTML file is generated by markdown.</p><p style="margin-top: 12px; margin-bottom: 12px; margin-left: 0px; margin-right: 0px; "></p><img src ="http://www.cppblog.com/deercoder/aggbug/180038.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/deercoder/" target="_blank">deercoder</a> 2012-06-24 16:57 <a href="http://www.cppblog.com/deercoder/archive/2012/06/24/180038.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>