﻿<?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++博客-gujiayue-随笔分类-C/C++</title><link>http://www.cppblog.com/gujiayue/category/17719.html</link><description /><language>zh-cn</language><lastBuildDate>Mon, 30 May 2016 09:01:06 GMT</lastBuildDate><pubDate>Mon, 30 May 2016 09:01:06 GMT</pubDate><ttl>60</ttl><item><title>输入输出缓冲区和流的概念理解</title><link>http://www.cppblog.com/gujiayue/archive/2016/05/27/213595.html</link><dc:creator>古月</dc:creator><author>古月</author><pubDate>Fri, 27 May 2016 08:10:00 GMT</pubDate><guid>http://www.cppblog.com/gujiayue/archive/2016/05/27/213595.html</guid><wfw:comment>http://www.cppblog.com/gujiayue/comments/213595.html</wfw:comment><comments>http://www.cppblog.com/gujiayue/archive/2016/05/27/213595.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/gujiayue/comments/commentRss/213595.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/gujiayue/services/trackbacks/213595.html</trackback:ping><description><![CDATA[<p style="text-indent:21.0pt;"><span style="font-family:宋体;">（本文章关于缓冲区概念的理解大部分取自：</span>http://developer.51cto.com/art/201107/277186.htm<span style="font-family:宋体;">）</span></p>  <p style="text-indent: 21pt;"><span style="font-family: 宋体;">快递的寄送过程：</span></p><p style="text-indent: 21pt;"><span style="font-family: 宋体;">源地址（商家的仓库）&#8212;&#8212;中转地（快递公司的仓库）&#8212;&#8212;目的地（买家）</span></p><p style="text-indent: 21pt;"><span style="font-family: 宋体;">我们从淘宝商家买衣服，商家通过快递公司把商品送到我们手里的这个过程可以形象的解释下缓存区和流的这个概念。</span></p><p style="margin-left: 39pt; text-indent: -18pt;">1，&nbsp;<span style="font-family: 宋体;">淘宝商家不会亲自把商品给买家送过来的，因为这样效率太低了，商家会通过快递公司这个中转，然后快递公司再把东西送给买家。淘宝商家就是在键盘上打字，买家就是程序，程序需要读取从键盘上的输入的字，缓冲区就是快递公司的仓库。</span></p><p style="margin-left: 39pt; text-indent: -18pt;">2，&nbsp;<span style="font-family: 宋体;">商品的几种位置状态：商家仓库，快递仓库，买家手中，还有一种状态就是在路上。输入输出的流就是指的在路上。</span></p><p style="margin-left: 39pt; text-indent: -18pt;">3，&nbsp;<span style="font-family: 宋体;">快递收货员收到商品就放到自己的中转仓库中。但是快递公司肯定等仓库中的商品积累到一定程度才开始派送。行缓冲就是遇到换行符时就认为需要执行</span>I/O<span style="font-family: 宋体;">操作了。<br /></span></p><p style="text-indent:21.0pt;"><span style="font-family:宋体;"><br /></span>&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;<span style="font-family:宋体;">一，缓冲区的概念</span></p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;">缓冲区又可以称为缓存。计算机中的内存可以被认为是硬盘的缓存。当</span>cpu<span style="font-family:宋体;">读取文件、执行程序时，不会直接从硬盘中读取，而是先把文件缓存到内存中，然后再从内存中读取。</span></p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;">对于</span>C++<span style="font-family:宋体;">程序来说，当类似</span>cin<span style="font-family:宋体;">，</span>getchar<span style="font-family:宋体;">这样的对象或者函数读取输入时，不会直接直接读键盘上的输入，而是这样的一个过程：</span>cin<span style="font-family:宋体;">&#8212;&#8212;输入缓冲区&#8212;&#8212;键盘。我们从键盘上输入的字符先存到缓冲区里面，</span>cin<span style="font-family:宋体;">从缓冲区里面读取输入。对于输出来说，程序的结果不会直接显示到屏幕上，而是先存放到缓冲区，然后</span>cout<span style="font-family:宋体;">把内容从缓冲区输出到屏幕。</span>cin<span style="font-family:宋体;">和</span>cout<span style="font-family:宋体;">本质上都是对缓冲区中的内容进行操作。</span></p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;">如果没有缓冲区就会大大降低</span>CPU<span style="font-family:宋体;">的效率，因为</span>cpu<span style="font-family:宋体;">将不得不一直等待用户的输入，而不能执行其他的操作，人打字输入的速度再快，也比不上</span>CPU<span style="font-family:宋体;">的执行速度，人在输入两个字符之间的间隔时间，</span>cpu<span style="font-family:宋体;">完全可以去干别的事情。</span></p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;">缓冲区分为三种全缓冲、行缓冲和不带缓冲。</span></p>  <p style="text-indent:21.0pt;">1<span style="font-family:宋体;">、全缓冲</span></p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;">在这种情况下，当填满标准</span>I/O<span style="font-family:宋体;">缓存后才进行实际</span>I/O<span style="font-family:宋体;">操作。全缓冲的典型代表是对磁盘文件的读写。</span></p>  <p style="text-indent:21.0pt;">2<span style="font-family:宋体;">、行缓冲</span></p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;">在这种情况下，当在输入和输出中遇到换行符时，执行真正的</span>I/O<span style="font-family:宋体;">操作。这时，我们输入的字符先存放在缓冲区，等按下回车键换行时才进行实际的</span>I/O<span style="font-family:宋体;">操作。典型代表是键盘输入数据。</span></p>  <p style="text-indent:21.0pt;">3<span style="font-family:宋体;">、不带缓冲</span></p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;">也就是不进行缓冲，标准出错情况</span>stderr<span style="font-family:宋体;">是典型代表，这使得出错信息可以直接尽快地显示出来。</span></p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;">缓冲区的刷新指的是缓冲区的内容被清空刷新，这也就意味着刷新之前系统会对缓冲区内容进行</span>I/O<span style="font-family:宋体;">读写。下面</span>4<span style="font-family:宋体;">种情况会触发缓冲区的刷新：</span></p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;">缓冲区满时；</span></p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;">执行</span>flush<span style="font-family:宋体;">语句；</span></p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;">执行</span>endl<span style="font-family:宋体;">语句；</span></p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;">关闭文件。</span></p>  <p style="text-indent:21.0pt;">C/C++<span style="font-family:宋体;">程序里面的缓冲区指的是为标准输入与标准输出设置的缓冲区，如果我们不认为的设置的话，系统会自动的为标准输入与标准输入设置一个缓冲区，这个缓冲区的大小通常是</span>4Kb<span style="font-family:宋体;">的大小。</span></p>  <p style="text-indent:21.0pt;">ANSI C<span style="font-family:宋体;">要求下列缓存特征：</span> </p>  <p style="text-indent:21.0pt;">(1) <span style="font-family:宋体;">当且仅当标准输入和标准输出并不涉及交互作用设备（键盘，屏幕）时，它们才是全缓存的。</span> <span style="font-family:宋体;">读写文件的时候就是全缓存。</span></p>  <p style="text-indent:21.0pt;">(2)<span style="font-family:宋体;">标准出错决不会是全缓存的。</span> </p>  <p style="text-indent:21.0pt;">(3)<span style="font-family:宋体;">标准输入和输出涉及交互作用设备时，虽然没有明确规定是不带缓存的还是行缓存的，但一般系统默认它们是行缓存的。</span> </p>  <p style="text-indent:21.0pt;">&nbsp;<span style="font-family:宋体;">因此我们经常要用的标准输入和输出，</span>stdin<span style="font-family:宋体;">、</span>stdout<span style="font-family:宋体;">和</span>stderr<span style="font-family:宋体;">的缓存特征是：</span>stdin<span style="font-family:宋体;">和</span>stdout<span style="font-family:宋体;">是行缓存；而</span>stderr<span style="font-family:宋体;">是无缓存的。</span>cin<span style="font-family:宋体;">和</span>cout<span style="font-family:宋体;">都是从缓冲区读取</span></p>  <p style="text-indent:21.0pt;">&nbsp;</p>  <p style="text-indent:21.0pt;">&nbsp;</p>  <p style="text-indent:21.0pt;">&nbsp;</p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;">二、流的概念</span></p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;">流是一个过程，一个动态的概念。可以把流想象成水在水管中流动的过程，想象成商品快递运送的过程。</span>Cin<span style="font-family:宋体;">和</span>cout<span style="font-family:宋体;">就是执行流这个过程的人。</span></p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;">对于输入，</span>cin<span style="font-family:宋体;">负责把输入缓冲区中的内容传递给程序；</span></p>  <p style="text-indent:21.0pt;"><span style="font-family:宋体;">对于输出，</span>cout<span style="font-family:宋体;">负责把输出缓冲区中的内容传递给屏幕。</span></p>  <p style="text-indent:21.0pt;">Cin<span style="font-family:宋体;">和</span>cout<span style="font-family:宋体;">把缓冲区的数据变成流，然后搬运到相应的目的地。</span>Cin<span style="font-family:宋体;">和</span>cout<span style="font-family:宋体;">就是个搬运工，搬运的过程就是流。</span></p>  <p style="text-indent:21.0pt;"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;三、代码案例<br />&nbsp; &nbsp; &nbsp; 第一段代码：</p><div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all; background-color: #eeeeee;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="font-size: 13px; color: #0000ff;">int</span><span style="font-size: 13px;">&nbsp;main()</span><br /><span style="font-size: 13px;">{</span><br /><span style="font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 13px; color: #0000ff;">string</span><span style="font-size: 13px;">&nbsp;str;</span><br /><span style="font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 13px; color: #0000ff;">int</span><span style="font-size: 13px;">&nbsp;i=0;</span><br /><span style="font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 13px; color: #0000ff;">while</span><span style="font-size: 13px;">&nbsp;(cin&nbsp;&gt;&gt;&nbsp;str)</span><br /><span style="font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;{</span><br /><span style="font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;str&lt;&lt;endl;</span><br /><span style="font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;++i&nbsp;&lt;&lt;&nbsp;endl;</span><br /><span style="font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;}</span><br /><span style="font-size: 13px;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 13px; color: #0000ff;">return</span><span style="font-size: 13px;">&nbsp;0;</span><br /><span style="font-size: 13px;">}</span><br /><span style="font-size: 13px;">程序执行过程中输入：i love you<br />最终结果是：<br /></span><span style="font-size: 13px;">i<br />1<br />love<br />2<br />you<br />3</span></div><p style="margin-left:39.0pt;text-indent:-18.0pt;"><span style="font-family: 宋体;">执行过程中，程序并不会在每次输入一个空格时就打印一次，而在在完全输入一行字符串并摁下回车后，才会打印。原因就是在我们输入回车之前的一行字符串都只是存放到了为标准输入分配的缓冲区中，这是一个行缓冲区，在遇到换行符之前，缓冲区不会刷新也就不会触发I/O操作，cin也就没有在读取数据。输入回车后，cin开始执行I/O操作，读取缓冲区中的字符：首先读取i，然后遇到了空格，此次读取完成，执行循环。然后接着读取love，又遇到了空格，读取完成，执行循环。最后读取了you。<br />第二段代码：<br /></span></p><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 />--><span style="color: #0000FF; ">int</span>&nbsp;main()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;c;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">第一次调用getchar()函数&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">程序执行时，您可以输入一串字符并按下回车键，按下回车键后该函数才返回&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;c&nbsp;=&nbsp;getchar();<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">显示getchar()函数的返回值&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;&lt;&lt;&nbsp;c&nbsp;&lt;&lt;&nbsp;endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">暂停&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;system("PAUSE");<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">循环多次调用getchar()函数&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">将每次调用getchar()函数的返回值显示出来&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">直到遇到回车符才结束&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">while</span>&nbsp;((c&nbsp;=&nbsp;getchar())&nbsp;!=&nbsp;'\n')<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%c",&nbsp;c);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">//</span><span style="color: #008000; ">暂停&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;system("PAUSE");<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;0;<br />}<br />执行程序，输入：abcdefg,然后回车<br />程序结果如下：<br />a<br />bcdefg</div><p style="margin-left:39.0pt;text-indent:-18.0pt;"><span style="font-family: 宋体;">第一次执行到getchar时，由于此时缓冲区里面没有任何内容，所以程序等待键盘的输入，输入abcdefg后，然后输入回车，触发了行缓冲的条件，执行I/O，getchar开始读取缓冲区的内容，由于此函数只读取一个字符，所以读完字符a后，读取结束，执行下面的语句，将a打印到屏幕。由于缓冲区中字符只被读取了1个字符a，剩余的bcdefg还在缓冲区中，因此执行到while中的getchar时，直接读取缓冲区中的内容，也就是依次读取bcdefg，回车符也是缓冲区中的一个字符，当读取完回车后，while循环结束。<br /><br /><br /></span></p><img src ="http://www.cppblog.com/gujiayue/aggbug/213595.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/gujiayue/" target="_blank">古月</a> 2016-05-27 16:10 <a href="http://www.cppblog.com/gujiayue/archive/2016/05/27/213595.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>c++中explict关键字的说明和使用</title><link>http://www.cppblog.com/gujiayue/archive/2012/09/19/191270.html</link><dc:creator>古月</dc:creator><author>古月</author><pubDate>Wed, 19 Sep 2012 10:15:00 GMT</pubDate><guid>http://www.cppblog.com/gujiayue/archive/2012/09/19/191270.html</guid><wfw:comment>http://www.cppblog.com/gujiayue/comments/191270.html</wfw:comment><comments>http://www.cppblog.com/gujiayue/archive/2012/09/19/191270.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/gujiayue/comments/commentRss/191270.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/gujiayue/services/trackbacks/191270.html</trackback:ping><description><![CDATA[<span style="font-size: 13px; color: #008080; ">先看下面这一个简单的代码吧<br /><br /></span><span style="font-size: 13px; color: #008080; ">&nbsp;1</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;#include&nbsp;&lt;iostream&gt;</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">&nbsp;2</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;</span><span style="font-size: 13px; color: #0000ff; ">using</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;</span><span style="font-size: 13px; color: #0000ff; ">namespace</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;std;</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">&nbsp;3</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;</span><span style="font-size: 13px; color: #0000ff; ">class</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;my</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">&nbsp;4</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;{</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">&nbsp;5</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;</span><span style="font-size: 13px; color: #0000ff; ">private</span><span style="font-size: 13px; background-color: #eeeeee; ">:</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">&nbsp;6</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 13px; color: #0000ff; ">int</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;t;</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">&nbsp;7</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;</span><span style="font-size: 13px; color: #0000ff; ">public</span><span style="font-size: 13px; background-color: #eeeeee; ">:</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">&nbsp;8</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my(){};</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">&nbsp;9</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my(</span><span style="font-size: 13px; color: #0000ff; ">int</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;i):t(i){};</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">10</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 13px; color: #0000ff; ">int</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;</span><span style="font-size: 13px; color: #0000ff; ">get</span><span style="font-size: 13px; background-color: #eeeeee; ">()</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">11</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">12</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 13px; color: #0000ff; ">return</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;t;</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">13</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">14</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 13px; color: #0000ff; ">void</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;print(my&nbsp;d)</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">15</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">16</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;d.</span><span style="font-size: 13px; color: #0000ff; ">get</span><span style="font-size: 13px; background-color: #eeeeee; ">()&lt;&lt;endl;</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">17</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">18</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;};</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">19</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">20</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;</span><span style="font-size: 13px; color: #0000ff; ">int</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;main()</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">21</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;{</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">22</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my&nbsp;t;</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">23</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 13px; color: #0000ff; ">int</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;i=3;</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">24</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t.print(i);</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">25</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 13px; color: #0000ff; ">return</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;0;</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; ">26</span><span style="font-size: 13px; background-color: #eeeeee; ">&nbsp;}</span><br style="font-size: 13px; " /><span style="font-size: 13px; color: #008080; "><br /></span><span style="font-size: 14pt; ">main函数中t.print(i);的调用，my类里面print函数接受的数据类型的my，不是int，但这段程序仍然能够正常运行，是因为my类里面存在一个只有一个形参的构造函数。<br /></span><br style="font-size: 13px; " /><span style="font-size: 14pt; ">当在一个需要my类型对象的地方（比如print函数，就需要一个my类型对象），但是如果却没有给一个my类型对象，给了一个其他类型的对象，比如int，那么这个时候就会看这个类有没有定义一个只接受一个参数的构造函数，而且这个形参必须是int，然后构造出一个my类型临时对象，再把这个临时对象给需要my类对象的地方，完成一种隐式的转换。</span><br style="font-size: 13px; " /><span style="font-size: 14pt; ">注意：如果这个类有一个接受一个参数的构造函数，但是这个参数的类型比如是string，这个隐式转换肯定就不会发生了，编译时会提示错误。<br /></span><br style="font-size: 13px; " /><span style="font-size: 14pt; ">总之，隐式转换会发生在，本来需要一个这种类对象的时候，却给了一个其他的数据类型，而且类也恰好有一个只接受一个这种数据类型参数的构造函数，就会先调用这个构造函数生成一个临时对象，接着将这临时对象用于需要这种类对象的地方。</span><br style="font-size: 13px; " /><br style="font-size: 13px; " /><span style="font-size: 14pt; ">但是很多时候，这种隐式转换会带来很大的麻烦，因此如果自己定义的类中，有一个只接受一个参数的构造函数，</span><span style="font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; line-height: 19px; background-color: #fefef2; font-size: 14pt; ">除非有一个好理由允许构造函数被用于隐式类型转换，否则</span><span style="font-size: 14pt; ">那么就要在这个构造函数前面加一个关键词 explicit，表明不会发生隐式转换。</span><img src ="http://www.cppblog.com/gujiayue/aggbug/191270.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/gujiayue/" target="_blank">古月</a> 2012-09-19 18:15 <a href="http://www.cppblog.com/gujiayue/archive/2012/09/19/191270.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>再谈下声明、定义、初始化、赋值和extern</title><link>http://www.cppblog.com/gujiayue/archive/2012/06/07/177916.html</link><dc:creator>古月</dc:creator><author>古月</author><pubDate>Thu, 07 Jun 2012 07:41:00 GMT</pubDate><guid>http://www.cppblog.com/gujiayue/archive/2012/06/07/177916.html</guid><wfw:comment>http://www.cppblog.com/gujiayue/comments/177916.html</wfw:comment><comments>http://www.cppblog.com/gujiayue/archive/2012/06/07/177916.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/gujiayue/comments/commentRss/177916.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/gujiayue/services/trackbacks/177916.html</trackback:ping><description><![CDATA[虽然定义也是声明，但为了方便说明问题，下文中的声明只是单纯的声明，定义就只是定义。<br /><p style="margin-left:18.0pt;text-indent:-18.0pt;">1.<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-family:宋体;">声明、定义、初始化和赋值四个术语有着本质的不同，虽然有时候看起来差不多甚至完全一样，但如果不搞清楚很容易出现错误，或者错了不知道怎么改。</span></p>  <p style="margin-left:18.0pt;text-indent:0cm;">&nbsp;</p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;">2.<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp; &nbsp; &nbsp;</span>a: extern<span style="font-family:宋体;">关键词用来表明这是一个声明：</span>extern int I;<span style="font-family:宋体;">变量</span>i<span style="font-family:宋体;">就是一个声明。</span><span style="font-family: 宋体; color: red; ">声明前面一定要有一个关键字</span><span style="color: red; ">extern</span><span style="font-family: 宋体; color: red; ">，没有这个关键词就不是一个声明。</span></p>  <p style="margin-left:18.0pt">b: <span style="font-family:宋体;">没有</span>extern<span style="font-family:宋体;">就是一个定义，比如</span>int i=9<span style="font-family:宋体;">；是一个定义，特别要注意的是</span><span style="color: red; ">int i;</span><span style="font-family: 宋体; color: red; ">这也是一个定义。</span></p>  <p style="margin-left:18.0pt">c: <span style="font-family:宋体;">初始化就是在变量定义时给变量一个初值，所以初始化语句也一定是一个定义语句，但反过来就不对了，因为类似于：</span>int i<span style="font-family:宋体;">；就是定义，但没有初始化。特别要注意的是：</span><span style="color: red; ">extern int i = 9</span><span style="font-family: 宋体; color: red; ">；虽然有</span><span style="color: red; ">extern</span><span style="font-family: 宋体; color: red; ">关键词，但是因为初始化了，所以这也是一个定义</span><span style="font-family:宋体;">，不是声明。</span></p>  <p style="margin-left:18.0pt">d: <span style="font-family:宋体;">赋值语句就简单了，赋值语句是给一个已经定义的变量（不管这个变量有没有初始化）一个新值。特别要注意的是，</span><span style="font-family: 宋体; color: red; ">要给赋值的变量必须已经定义过了，仅仅声明是不行的。</span></p>  <p style="margin-left:18.0pt">&nbsp;</p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;">3.<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>extern<span style="font-family:宋体;">关键词除了表明这是一个声明以外，更重要的是表明：所声明的变量的定义可能是在程序中其他文件里。如下代码<br /><br /></span></p><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 />--><span style="color: #008000; ">&nbsp; &nbsp; //</span><span style="color: #008000; ">file1.cpp</span><span style="color: #008000; "><br /></span><br />#include&nbsp;&lt;iostream&gt;<br /><span style="color: #0000FF; ">using</span>&nbsp;<span style="color: #0000FF; ">namespace</span>&nbsp;std;<br /><span style="color: #0000FF; ">extern</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;i;<span style="color: #008000; ">//</span><span style="color: #008000; ">这是一个声明，告诉编译器变量i的定义有可能是在其他源文件中，即使本文件中没有i的定义，你也不要报错。</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">void</span>&nbsp;main()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">extern</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;i;<span style="color: #008000; ">//</span><span style="color: #008000; ">同样是对i的声明，作用与上面的声明完全一样，说明声明可以存在多个，实际上这两个声明只要任意一个就可以了。但是两个声明语句如果一个都没有，编译器就会认为变量i没有定义，会报错。<br /></span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;i=0;<span style="color: #008000; ">//</span><span style="color: #008000; ">赋值语句，给变量i一个新值，变量赋值前必须要已经定义了，如果不存在file2文件中的定义语句，虽然不会出现编译错误，但是链接会有错。</span><span style="color: #008000; "><br /></span>&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;i;<br />}<br /><br /><span style="color: #008000; ">//</span><span style="color: #008000; ">file2.cpp</span><span style="color: #008000; "><br /></span><br /><span style="color: #0000FF; ">int</span>&nbsp;i;<span style="color: #008000; ">//</span><span style="color: #008000; ">首先是一个定义，而且是一个没有初始化的定义（不过实际上全局变量i被默认初始化为0），变量i被定义在file2源文件中</span></div><p>&nbsp;</p>  <p style="margin-left:18.0pt;text-indent:0cm;">&nbsp;</p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;">4.<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-family:宋体;">一个程序中可能包括不只一个文件，所有文件中同一个变量（其实主要说的全局变量）必须总共只能定义一次，但是声明可以有无数个。而且如果</span><span style="font-family: 宋体; color: red; ">文件</span><span style="color: red; ">A</span><span style="font-family: 宋体; color: red; ">中用到的变量的定义是在其他文件中，那么在文件</span><span style="color: red; ">A</span><span style="font-family: 宋体; color: red; ">中用这个变量之前，一定要加上一句</span><span style="color: red; ">extern</span><span style="font-family: 宋体; color: red; ">声明语句，告诉编译器我所用的这个变量有可能是在其他文件里</span><span style="font-family:宋体;"><br /><br /></span></p>  <p>5. &nbsp; extern int i=9；上面已经提到虽然有extern，但这也是一个定义，因为初始化了。<span style="color: red; ">类似于这种有extern也有初始化的语句，只能出现在全局作用域，如果出现在函数内部，这是错误的。</span><br /><br /></p>  <p style="margin-left:18.0pt;text-indent:-18.0pt;">6.<span style="font-family: 'Times New Roman'; font-size: 7pt; line-height: normal; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family:宋体;">（转）有关编译器的一个特点：</span><span style="font-family: 宋体; color: red; ">现代编译器一般都属于按文件编译，就是说编译时多个源文件自己编译自己的，互不影响，好像只有自己一个文件。</span><span style="font-family:宋体;">只要每个文件编译时没有出现错误，那么就不会发生编译时错误。但是</span><span style="font-family: 宋体; color: red; ">没有发生编译错误，并不代表程序就没有错误，因为还会发生链接错误</span><span style="font-family:宋体;">。比如下面这两个代码<br /></span></p><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 />--><span style="color: #008000; ">&nbsp; &nbsp; &nbsp;//</span><span style="color: #008000; ">A.cpp</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">int</span>&nbsp;i;<span style="color: #008000; ">//</span><span style="color: #008000; ">这是变量i的定义</span><span style="color: #008000; "><br /></span>&nbsp;<br /><span style="color: #0000FF; ">void</span>&nbsp;main()<br />{<br />}<br /><br /><span style="color: #008000; ">//</span><span style="color: #008000; ">B.cpp</span><span style="color: #008000; "><br /></span><span style="color: #0000FF; ">int</span>&nbsp;i;<span style="color: #008000; ">//</span><span style="color: #008000; ">这也是变量i的定义</span></div><span style="font-family:宋体;">编译时两个文件A和B是相互不影响的，所以编译时不会出现任何错误，但是这个程序是有问题的，因为全局变量i是被定义了两次的，所以链接时就会报告类似于下面的错误：<br /></span><p class="MsoNormal" style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #e0e0e0; margin-top: 0pt; margin-right: 0pt; margin-bottom: 0pt; margin-left: 0pt; "><span lang="EN-US" style="font-size: 9pt; "><font face="Times New Roman">B.obj : error LNK2005: "int i" (?i@@<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="3" unitname="ha">3HA</chmetcnv>) already defined in A.obj</font></span></p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #e0e0e0; "></p><p style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #e0e0e0; "></p><p class="MsoNormal" style="color: #333333; font-family: Arial; line-height: 26px; text-align: left; background-color: #e0e0e0; margin-top: 0pt; margin-right: 0pt; margin-bottom: 0pt; margin-left: 0pt; "><span lang="EN-US" style="font-size: 9pt; "><font face="Times New Roman">Debug/A.exe : fatal error LNK1169: one or more multiply defined symbols found</font></span></p><span style="font-family:宋体;">另外上面也提到了，编译时各个文件是相互不影响的，编译器是不会认为在这个文件中没有定义的变量其实很有可能人家是个全局变量，在其他文件中定义了，这就要报错。解决方法就是用</span><span style="font-family: 宋体; color: red; ">extern声明一个变量，告诉编译器人家这个变量不是没有定义，只是在其他文件中定义了</span><span style="font-family:宋体;">，你别报错了。</span><p>&nbsp;</p><img src ="http://www.cppblog.com/gujiayue/aggbug/177916.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/gujiayue/" target="_blank">古月</a> 2012-06-07 15:41 <a href="http://www.cppblog.com/gujiayue/archive/2012/06/07/177916.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>新学到的有关cin输入流的特点、用法</title><link>http://www.cppblog.com/gujiayue/archive/2012/05/28/cin.html</link><dc:creator>古月</dc:creator><author>古月</author><pubDate>Sun, 27 May 2012 16:20:00 GMT</pubDate><guid>http://www.cppblog.com/gujiayue/archive/2012/05/28/cin.html</guid><wfw:comment>http://www.cppblog.com/gujiayue/comments/176424.html</wfw:comment><comments>http://www.cppblog.com/gujiayue/archive/2012/05/28/cin.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/gujiayue/comments/commentRss/176424.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/gujiayue/services/trackbacks/176424.html</trackback:ping><description><![CDATA[<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 />-->#include&nbsp;&lt;iostream&gt;<br /><br /><span style="color: #0000FF; ">using</span>&nbsp;<span style="color: #0000FF; ">namespace</span>&nbsp;std;<br /><span style="color: #0000FF; ">void</span>&nbsp;main()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">double</span>&nbsp;val;<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">char</span>&nbsp;ch0,ch1;<br />&nbsp;&nbsp;&nbsp;&nbsp;cin&gt;&gt;val;<br />&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;val&lt;&lt;endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;cin&gt;&gt;ch0;<br />&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;ch0&lt;&lt;endl;<br />&nbsp;&nbsp;&nbsp;&nbsp;cin&gt;&gt;ch1;<br />&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;ch1&lt;&lt;endl;<br />}<br /><br />cin输入流用法之前学的不认真，忽略到了。<br />这段代码很简单，开始第一个输入的时候，比如直接输入：123ab。最后的结果是把123给了val，a给了ch0,b给了ch1。<br />也就是说，当cin给一个double时，这时如果你的输入是123ab，不是单纯的一个数字时，那么将只是把输入的数字部分123给double，<span style="color: red; "><strong>但是剩下的ab不是简单的遗弃掉</strong></span>，而是继续留在输入流中，等待下一次出现cin再把ab给到下一个要从输入流得到值的变量。</div><img src ="http://www.cppblog.com/gujiayue/aggbug/176424.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/gujiayue/" target="_blank">古月</a> 2012-05-28 00:20 <a href="http://www.cppblog.com/gujiayue/archive/2012/05/28/cin.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>鄙人这辈子编写的第一个游戏程序：猜拳！ 好激动，共享下c++源代码</title><link>http://www.cppblog.com/gujiayue/archive/2012/01/13/164145.html</link><dc:creator>古月</dc:creator><author>古月</author><pubDate>Fri, 13 Jan 2012 14:30:00 GMT</pubDate><guid>http://www.cppblog.com/gujiayue/archive/2012/01/13/164145.html</guid><wfw:comment>http://www.cppblog.com/gujiayue/comments/164145.html</wfw:comment><comments>http://www.cppblog.com/gujiayue/archive/2012/01/13/164145.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/gujiayue/comments/commentRss/164145.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/gujiayue/services/trackbacks/164145.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 石头剪子布的猜拳游戏，在VC下编译运行下，生成的.EXE文件，就可以单独拿出来玩游戏了。这个游戏属于1.1版本，最原始的1.0版本主要部分和这个差不多，1.1主要是在原来的基础上与玩家的交互做了一些更加友好的改进（感谢提出改进意见的宿舍兄弟）程序基本没有太大的技术含量，自认为程序核心的部分:电脑随机给出的猜拳。本人想到了一个很简单但自认为挺巧妙的方法（小小的骄傲下），不多说了看代码吧，如果代码有什...&nbsp;&nbsp;<a href='http://www.cppblog.com/gujiayue/archive/2012/01/13/164145.html'>阅读全文</a><img src ="http://www.cppblog.com/gujiayue/aggbug/164145.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/gujiayue/" target="_blank">古月</a> 2012-01-13 22:30 <a href="http://www.cppblog.com/gujiayue/archive/2012/01/13/164145.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>字符串操作函数中的参数问题</title><link>http://www.cppblog.com/gujiayue/archive/2011/12/25/162780.html</link><dc:creator>古月</dc:creator><author>古月</author><pubDate>Sun, 25 Dec 2011 08:25:00 GMT</pubDate><guid>http://www.cppblog.com/gujiayue/archive/2011/12/25/162780.html</guid><wfw:comment>http://www.cppblog.com/gujiayue/comments/162780.html</wfw:comment><comments>http://www.cppblog.com/gujiayue/archive/2011/12/25/162780.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/gujiayue/comments/commentRss/162780.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/gujiayue/services/trackbacks/162780.html</trackback:ping><description><![CDATA[<div>这个首先先解释下一个很基础但是却很重要又常常容易搞混的问题。<br />char a[]和char*的区别。<br />《c语言程序设计》（中文版）的解释挺不错的，我再大概说一下。<br />..............................<br />char ame[] = "nw is the time"; <br />char *pme = "now is the time";<br />首先说pme是把一个指向该字符数组的指针赋值给pme.这个过程没有涉及到字符串的复制，只是有指针的操作。pme首先是一个指针，这个指针指向一个字符串常量，这个指针此后可以被修改为指向其它字符串，但是如果修改字符串本身的内容，结果是未定义的。ame是一个存放初始化字符串和空字符的一维数组，数组中的单个字符都是可以被修改的，但是ame是个地址常量，是不可以被修改的，它始终指向这一个字符串。<br /><br />string.h中定义了很多字符串操作函数，比如strncat，这些函数至少都有两个参数，第一个参数是目的字符串，第二个参数是源字符串。<br />关于这个参数的类型到底用哪种，<strong style="color: #ff0000; font-size: 14pt">要看相关的参数内容在函数执行完以后是不是会发生改变。如果参数内容发生改变了就要用char[]，如果参数的内容不发生改变则两个都可以用。</strong><strong><br /><br /></strong>比如strncat（s,ct,n)，函数的作用是把ct的前n个字符连接到s的后面，最后补上一个空字符。那么显然执行完以后s的内容是变化了的，所以定义s是必须是char s[80]，不能是char *s，对于ct来说内容没有发生变化，怎么定义就都可以了。</div><img src ="http://www.cppblog.com/gujiayue/aggbug/162780.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/gujiayue/" target="_blank">古月</a> 2011-12-25 16:25 <a href="http://www.cppblog.com/gujiayue/archive/2011/12/25/162780.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>fopen函数的使用的几种方式</title><link>http://www.cppblog.com/gujiayue/archive/2011/12/25/162775.html</link><dc:creator>古月</dc:creator><author>古月</author><pubDate>Sun, 25 Dec 2011 06:08:00 GMT</pubDate><guid>http://www.cppblog.com/gujiayue/archive/2011/12/25/162775.html</guid><wfw:comment>http://www.cppblog.com/gujiayue/comments/162775.html</wfw:comment><comments>http://www.cppblog.com/gujiayue/archive/2011/12/25/162775.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/gujiayue/comments/commentRss/162775.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/gujiayue/services/trackbacks/162775.html</trackback:ping><description><![CDATA[<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">#include</span><span style="color: #000000">&lt;</span><span style="color: #000000">stdio.h</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />#include</span><span style="color: #000000">&lt;</span><span style="color: #0000ff">string</span><span style="color: #000000">.h</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />&nbsp;<br /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;main()<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;FILE&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;handle;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;con[</span><span style="color: #000000">100</span><span style="color: #000000">];<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">第一种使用fopen的方式，windows系统是直接输入文件的绝对路径需要这种方式"e:\\aaa.txt",注意是两个反斜杠，一个反斜杠的话就错了<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">handle=fopen("e:\aaa.txt","r");<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">第二种使用fopen的方式，利用一个字符串来保存文件路径和名字，运行程序后，在dos下提示你输入路径名字，可以输入"e:\\aaa.txt"，<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">或者"e:\aaa.txt"，也就是说dos下一个反斜杠或者两个反斜杠都是正确的<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">char&nbsp;buf[80];<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">printf("please&nbsp;input&nbsp;the&nbsp;filename&nbsp;you&nbsp;want&nbsp;to&nbsp;open:");<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">gets(buf);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">handle=fopen(buf,"r");<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">利用一个初始化好的字符串也可以正确的使用fopen，以下这几种初始化方式都是正确的都是两个反斜杠<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">char&nbsp;buf[]="e:\\aaa.txt";const&nbsp;char&nbsp;buf[100]="e:\\aaa.txt";</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">char</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">buf</span><span style="color: #000000">=</span><span style="color: #000000">"</span><span style="color: #000000">e:\\aaa.txt</span><span style="color: #000000">"</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;handle</span><span style="color: #000000">=</span><span style="color: #000000">fopen(buf,</span><span style="color: #000000">"</span><span style="color: #000000">r</span><span style="color: #000000">"</span><span style="color: #000000">);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">(</span><span style="color: #000000">!</span><span style="color: #000000">handle)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror(</span><span style="color: #000000">"</span><span style="color: #000000">can&nbsp;not&nbsp;open&nbsp;this&nbsp;file\n</span><span style="color: #000000">"</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000"><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">you&nbsp;have&nbsp;opened&nbsp;this&nbsp;file&nbsp;successfully!\n</span><span style="color: #000000">"</span><span style="color: #000000">);<br />&nbsp;&nbsp;&nbsp;&nbsp;fgets(con,</span><span style="color: #000000">100</span><span style="color: #000000">,handle);<br />&nbsp;&nbsp;&nbsp;&nbsp;printf(</span><span style="color: #000000">"</span><span style="color: #000000">the&nbsp;content&nbsp;of&nbsp;file&nbsp;is:%s\n</span><span style="color: #000000">"</span><span style="color: #000000">,con);<br />&nbsp;&nbsp;&nbsp;&nbsp;fclose(handle);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />}</span></div><br />主要介绍了fopen函数的第一个参数的使用，代码里面说的已经很清楚了，其余类似fopen的函数的使用也一样<img src ="http://www.cppblog.com/gujiayue/aggbug/162775.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/gujiayue/" target="_blank">古月</a> 2011-12-25 14:08 <a href="http://www.cppblog.com/gujiayue/archive/2011/12/25/162775.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux环境下调试有关涉及到条件编译的c程序的小用法</title><link>http://www.cppblog.com/gujiayue/archive/2011/09/14/155793.html</link><dc:creator>古月</dc:creator><author>古月</author><pubDate>Wed, 14 Sep 2011 15:56:00 GMT</pubDate><guid>http://www.cppblog.com/gujiayue/archive/2011/09/14/155793.html</guid><wfw:comment>http://www.cppblog.com/gujiayue/comments/155793.html</wfw:comment><comments>http://www.cppblog.com/gujiayue/archive/2011/09/14/155793.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/gujiayue/comments/commentRss/155793.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/gujiayue/services/trackbacks/155793.html</trackback:ping><description><![CDATA[条件编译，有三种格式<br />1 #if 表达式<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 程序段1<br />&nbsp; #else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 程序段2<br />&nbsp;#endif<br />&nbsp;&nbsp;&nbsp;很简单，表达式为真编译1，否则编译2。<br /><br />2 #ifdef 标识符<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;程序段1<br />&nbsp;&nbsp;&nbsp;#else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;程序段2<br />&nbsp;&nbsp;&nbsp;#endif<br />如果标识符已用#define定义过，则为真编译1，否则编译2<br /><br />3 和2的基本一致就是把ifdef换成ifndef。用法是为假编译1，否则2<br /><br />比如#include &lt;stdio.h&gt;<br />int main()<br />{<br />#ifdef _DEBUG<br />printf("hello world\n");<br />#else<br />printf("no debug");<br />#endif<br />return 0;<br />}<br /><br />在linux用gcc编译是，如果使用gcc -D_DEBUG -o main main.c。则就是说明定义过_DEBUG，运行结果是hello world。注意是-D选项，-D后面紧跟着标识符名字<br />如果使用：gcc -o main mian.c，怎说明没有定义标识符，运行结果是no debug了。<br /><br />当然，也可以直接再代码里显示写上一句：#define _DEBUG,也能有相同效果。<br /><br /><!--c2--><!--ec2--> <img src ="http://www.cppblog.com/gujiayue/aggbug/155793.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/gujiayue/" target="_blank">古月</a> 2011-09-14 23:56 <a href="http://www.cppblog.com/gujiayue/archive/2011/09/14/155793.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>宏定义的用法详解</title><link>http://www.cppblog.com/gujiayue/archive/2011/09/14/155791.html</link><dc:creator>古月</dc:creator><author>古月</author><pubDate>Wed, 14 Sep 2011 15:42:00 GMT</pubDate><guid>http://www.cppblog.com/gujiayue/archive/2011/09/14/155791.html</guid><wfw:comment>http://www.cppblog.com/gujiayue/comments/155791.html</wfw:comment><comments>http://www.cppblog.com/gujiayue/archive/2011/09/14/155791.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/gujiayue/comments/commentRss/155791.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/gujiayue/services/trackbacks/155791.html</trackback:ping><description><![CDATA[宏的使用的核心，就是替换，换是最关键的。<br /><br />1、不带参数的宏定义<br /><br />&nbsp; 这是最简单的了，比如#define PI 3.1415926<br />预编译的时候，把代码中的PI替换就行了。一般情况下宏名用大写字母，不要在行末加分号。<br /><br />2、带参数的宏定义<br /><br />不只是进行宏体的替换，还要进行参数的替换。<br />比如：#define MAX(x，y） （x&gt;y)?x:y<br />宏展开的时候要将语句中宏名后面的括号内的实参代替形参。另外为了避免发生错误，凡是带运算符的参数要用圆括号括起来。<br /><br />3、不常见但是很重要的用法<br />(1)#define FUN(a) "a"<br />那么当输入FUN(345)是，照样会被替换成&#8220;a&#8221;，无论宏的实参是什么，都不会影响其被替换成"a"的命运。 
<div class="spctrl"></div>　　也就是说，""内的字符不被当成形参，即使它和一模一样。<br />(2)有参宏定义中#的用法 <br />　#define STR(str) #str 
<div class="spctrl"></div>　　str前面的那个#用于把宏定义中的参数两端加上字符串的""<br />&nbsp;比如代码中有STR(my#name),那么在展开的时候被替换成"my#name"。<br />一般由任意字符都可以做形参，但以下情况会出错： 
<div class="spctrl"></div>　　STR())这样，编译器不会把&#8220;)&#8221;当成STR()的参数。 
<div class="spctrl"></div>　　STR(,)同上，编译器不会把&#8220;,&#8221;当成STR的参数。 
<div class="spctrl"></div>　　STR(A,B)如果实参过多，则编译器会把多余的参数舍去。（VC++2008为例） 
<div class="spctrl"></div>　　STR((A,B))会被解读为实参为：(A,B)，而不是被解读为两个实参，第一个是(A第二个是B)。 <br /><br />(3)&nbsp;有参宏定义中##的用法 <br />#define WIDE(str) L##str 
<div class="spctrl"></div>　　则会将形参str的前面加上L 
<div class="spctrl"></div>　　比如：WIDE("abc")就会被替换成L"abc" 
<div class="spctrl"></div>　　如果有#define FUN(a,b) vo##a##b() 
<div class="spctrl"></div>　　那么FUN(id ma,in)会被替换成void main() <br />再比如：<br />#define s5(a) supper_ ## a<br />#include &lt;stdio.h&gt;<br />void supper_printf(const char* p )<br />{<br />printf("this is supper printf:\n%s\n",a);<br />}<br /><br />int main()<br />{<br />s5(printf)("hello owrld");//就是调用函数supper_printf.<br />return 0;<br />}<br />(4) 多行宏定义： 
<div class="spctrl"></div>　　#define doit(m,n) for(int i=0;i&lt;(n);++i)\ 
<div class="spctrl"></div>　　{\ 
<div class="spctrl"></div>　　m+=i;\ 
<div class="spctrl"></div>　　}<br />关键是要在每一个换行的时候加上一个 "\ " ,最后一行不用加。这样使用的时候就可以用doit（m，n）来代替for循环结构了。<br /><!--c2--><!--ec2--> <img src ="http://www.cppblog.com/gujiayue/aggbug/155791.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/gujiayue/" target="_blank">古月</a> 2011-09-14 23:42 <a href="http://www.cppblog.com/gujiayue/archive/2011/09/14/155791.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>