<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Codes, Notes &#38; Scribbles &#187; C++</title>
	<atom:link href="http://blog.tomtung.com/tag/cpp/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.tomtung.com</link>
	<description>about programming, music and my life</description>
	<lastBuildDate>Sun, 15 Jan 2012 23:59:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>sinablog2wordpress：从新浪博客搬家到WordPress</title>
		<link>http://blog.tomtung.com/2010/02/sinablog2wordpress/</link>
		<comments>http://blog.tomtung.com/2010/02/sinablog2wordpress/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 13:23:16 +0000</pubDate>
		<dc:creator>逆铭</dc:creator>
				<category><![CDATA[新长征路上的代码]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Scala]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[博客搬家]]></category>

		<guid isPermaLink="false">http://blog.tomtung.com/?p=475</guid>
		<description><![CDATA[<a href="http://blog.tomtung.com/2010/02/sinablog2wordpress/" title="sinablog2wordpress：从新浪博客搬家到Wordpress"></a>要从新浪搬到Wordpres，网上广为流传的方法是利用blogbus的博客搬家服务获得blogbus格式的xml，然后再用一个Python写的脚本把它转换成WordPress认识的格式。但是这种方法在最近新浪博客升级以后就失效了。于是自己用现学的scala写了一个小程序，搬家时能保留标签、目录、评论及评论回复这些信息。 猛击[这里]下载。注意，此程序仅支持2010年初的新版新浪博客，之前或之后的版本都不支持。 要运行程序，你需要确保已经安装过JRE。双击运行后显示如图界面，填入自己的博客地址（不要省略“ http:// ”），然后点击“Start”即可。这时“Start”按钮变为灰色，标题栏显示“Extracting”。等待几分钟，当标题栏显示为“Done”、“Start”按钮重新变为可用时，程序所在目录下会出现一个blog.xml文件。把这个文件直接导入WordPress就可以了。 代码也打在jar包里了，MIT协议。欢迎报告bug。 下面是废话。 恩由于新浪用了ajax，评论信息是通过xhr异步读取的，用一般的方法没法抓到。我纠结许久，最后是用了非常ad hoc的方法解决的，不知道有没有什么什么不太麻烦的通用解决方案呢。 再扯两句scala。我都想不起来当初具体是怎么想到要学scala的，也许是为了了解下函数式编程，也许只是想在jvm上有一个喜欢的语言吧——Java写起来太不爽了；Java社区的低效和保守也已经开始显出C++的影子。 scala确实是非常强大和灵活；我在见到一些颇富技巧性的hack之后都有些怀疑scala社区的风气会不会慢慢变得像C++社区一样过分热衷技巧的炫耀。不过scala的设计目标就是以较简单的语法规则获得最大的scalability，不需要通过挖掘语言规范里的犄角旮旯来实现一些必要功能，所以不会像C++一样成为一门本身已相当复杂，却还需要别人反过来教语言发明者如何使用的语言。 scala毕竟表现力比Java强太多，代码也简洁太多。比如这次我需要实现一个抛出异常后重试若干次的逻辑，只需定义一个函数： def tryFor[T](times: Int)(op: =&#62; T): T = { if (times &#60;= 0) throw new RuntimeException("Operation failed.")  try { return op } catch {  case e: Throwable =&#62; e.printStackTrace &#8230;<p class="read-more"><a href="http://blog.tomtung.com/2010/02/sinablog2wordpress/">继续阅读 &#187;</a></p><hr/><blockquote>
可能你对下面的文章也感兴趣：<ol>
<li><a href='http://blog.tomtung.com/2009/03/try-template-meta-programming/' rel='bookmark' title='小试模板元编程'>小试模板元编程</a></li>
<li><a href='http://blog.tomtung.com/2008/10/first-month-in-buaa/' rel='bookmark' title='初来北航一个多月的零零碎碎'>初来北航一个多月的零零碎碎</a></li>
<li><a href='http://blog.tomtung.com/2008/09/cpp-primer-reding-notes-chapter8/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第八章'>C++ Primer 读书笔记 &#8211; 第八章</a></li>
</ol></blockquote>]]></description>
			<content:encoded><![CDATA[<a href="http://blog.tomtung.com/2010/02/sinablog2wordpress/" title="sinablog2wordpress：从新浪博客搬家到Wordpress"></a><div class="wp-caption alignnone" style="width: 430px"><a href="http://code.google.com/p/sinablog2wordpress/"><img title="http://upload.tomtung.com/img/sina2wordpress-screenshot.png" src="http://upload.tomtung.com/img/sina2wordpress-screenshot.png" alt="" width="420" height="80" /></a><p class="wp-caption-text">Screenshot</p></div>
<p>要从新浪搬到Wordpres，网上广为流传的方法是利用blogbus的博客搬家服务获得blogbus格式的xml，然后再用一个Python写的脚本把它转换成WordPress认识的格式。但是这种方法在最近新浪博客升级以后就失效了。于是自己用现学的scala写了一个小程序，搬家时能保留<strong>标签</strong>、<strong>目录</strong>、<strong>评论</strong>及<strong>评论回复</strong>这些信息。</p>
<p>猛击<strong><a href="http://sinablog2wordpress.googlecode.com/files/sina2wordpress.jar" target="_self">[这里]</a></strong>下载。注意，此程序仅支持2010年初的新版新浪博客，之前或之后的版本都不支持。</p>
<p>要运行程序，你需要确保已经安装过<a href="http://java.com/zh_CN/download/">JRE</a>。双击运行后显示如图界面，填入自己的博客地址（不要省略“ http:// ”），然后点击“Start”即可。这时“Start”按钮变为灰色，标题栏显示“Extracting”。等待几分钟，当标题栏显示为“Done”、“Start”按钮重新变为可用时，程序所在目录下会出现一个blog.xml文件。把这个文件直接导入WordPress就可以了。</p>
<p>代码也打在jar包里了，MIT协议。欢迎报告bug。</p>
<p>下面是废话。</p>
<p>恩由于新浪用了ajax，评论信息是通过xhr异步读取的，用一般的方法没法抓到。我纠结许久，最后是用了非常ad hoc的方法解决的，不知道有没有什么什么不太麻烦的通用解决方案呢。</p>
<p>再扯两句scala。我都想不起来当初具体是怎么想到要学scala的，也许是为了了解下函数式编程，也许只是想在jvm上有一个喜欢的语言吧——Java写起来太不爽了；Java社区的低效和保守也已经开始显出C++的影子。</p>
<p>scala确实是非常强大和灵活；我在见到一些颇富技巧性的hack之后都有些怀疑scala社区的风气会不会慢慢变得像C++社区一样过分热衷技巧的炫耀。不过scala的设计目标就是以较简单的语法规则获得最大的scalability，不需要通过挖掘语言规范里的犄角旮旯来实现一些必要功能，所以不会像C++一样成为一门本身已相当复杂，却还需要别人反过来教语言发明者如何使用的语言。</p>
<p>scala毕竟表现力比Java强太多，代码也简洁太多。比如这次我需要实现一个抛出异常后重试若干次的逻辑，只需定义一个函数：</p>
<pre class="brush:scala">def tryFor[T](times: Int)(op: =&gt; T): T = {
  if (times &lt;= 0) throw new RuntimeException("Operation failed.")
  try { return op } catch {
    case e: Throwable =&gt; e.printStackTrace
    tryFor(times - 1)(op)
  }
}</pre>
<p>然后这样使用：</p>
<pre class="brush:scala">val source = tryFor(5) {new Source(url)}</pre>
<p>程序就会不断获得网页源代码，并在5次失败后抛出异常。Java实现同样的东西可不会如此优雅了。又如下面这段代码返回一篇博文xml：</p>
<pre class="brush:scala">private def generateEntryXml(entry: BlogEntry) = {
  &lt;item&gt;
    &lt;title&gt;
      {entry.title}
    &lt;/title&gt;
    &lt;wp:post_date&gt;
      {dateFormat.format(entry.postDate)}
    &lt;/wp:post_date&gt;
    &lt;category&gt;
      {entry.category}
    &lt;/category&gt;
    {for (tag &lt;- entry.tags) yield &lt;category domain="tag"&gt;{tag}&lt;/category&gt;}
    &lt;content:encoded&gt;
      {xml.Unparsed(handleNewLines(entry.content))}
    &lt;/content:encoded&gt;
    &lt;wp:status&gt;publish&lt;/wp:status&gt;
    {for (comment &lt;- entry.comments) yield generateCommentXml(comment)}
  &lt;/item&gt;
}</pre>
<p>注意，xml标签直接作为scala的源代码的一部分在代码中出现！虽然我觉得这样会使scala语言多出一种“特殊情况”，增加语言的复杂性，但不得不承认这样的设计确实非常优美简洁。</p>
<p>我比较看好scala，以后自己做跑在jvm上的东西scala应该是首选语言。推荐有兴趣的童鞋也了解一下。</p>

<hr/><blockquote><p>可能你对下面的文章也感兴趣：</p><ol>
<li><a href='http://blog.tomtung.com/2009/03/try-template-meta-programming/' rel='bookmark' title='小试模板元编程'>小试模板元编程</a></li>
<li><a href='http://blog.tomtung.com/2008/10/first-month-in-buaa/' rel='bookmark' title='初来北航一个多月的零零碎碎'>初来北航一个多月的零零碎碎</a></li>
<li><a href='http://blog.tomtung.com/2008/09/cpp-primer-reding-notes-chapter8/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第八章'>C++ Primer 读书笔记 &#8211; 第八章</a></li>
</ol></blockquote>]]></content:encoded>
			<wfw:commentRss>http://blog.tomtung.com/2010/02/sinablog2wordpress/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>小试模板元编程</title>
		<link>http://blog.tomtung.com/2009/03/try-template-meta-programming/</link>
		<comments>http://blog.tomtung.com/2009/03/try-template-meta-programming/#comments</comments>
		<pubDate>Sun, 01 Mar 2009 06:37:57 +0000</pubDate>
		<dc:creator>逆铭</dc:creator>
				<category><![CDATA[新长征路上的代码]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://blog.tomtung.com/2009/03/%e5%b0%8f%e8%af%95%e6%a8%a1%e6%9d%bf%e5%85%83%e7%bc%96%e7%a8%8b/</guid>
		<description><![CDATA[<a href="http://blog.tomtung.com/2009/03/try-template-meta-programming/" title="小试模板元编程"></a>很久不更新了，再水一下吧。 前两天新开的数据结构课布置上机作业，里面又出现了不知道之前出现过多少次的输出质数。每次都交表也会很乏味，所以……这次还是要交表 &#8211; -&#124;&#124;&#124; 不过要玩一点小花样——让编译器在编译期把质数表算出来。 这个当然涉及到一点模板元编程了。之前虽然看了《Effective C++》里关于模板元的简介挺感兴趣，但看到《学习C++：实践者的方法》里告诫不要在这种“20%场景下的复杂性”上白花时间（“这些细节或技术在日常编程中极少用到，尤其是各种语言缺陷衍生出来的workarounds，构成了一个巨大的长尾……绝大多数只在库开发当中需要用到”），我一直对模板元编程敬而远之。这次也只是消遣一下，并无深入学习的打算。 以下是代码： #include &#60;iostream&#62; #include &#60;vector&#62; #include &#60;iterator&#62; #include &#60;algorithm&#62; std::vector&#60;int&#62; Primes; template &#60;int toTest, int factor&#62; // factor should be odd class IsPrime { public: enum { result = ( toTest == 2 &#8230;<p class="read-more"><a href="http://blog.tomtung.com/2009/03/try-template-meta-programming/">继续阅读 &#187;</a></p><hr/><blockquote>
可能你对下面的文章也感兴趣：<ol>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter2/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第二章'>C++ Primer 读书笔记 &#8211; 第二章</a></li>
<li><a href='http://blog.tomtung.com/2007/06/c-cpp-io-odd-behavior/' rel='bookmark' title='诡异的事：关于C/C++输入输出'>诡异的事：关于C/C++输入输出</a></li>
<li><a href='http://blog.tomtung.com/2008/09/cpp-primer-reding-notes-chapter8/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第八章'>C++ Primer 读书笔记 &#8211; 第八章</a></li>
</ol></blockquote>]]></description>
			<content:encoded><![CDATA[<a href="http://blog.tomtung.com/2009/03/try-template-meta-programming/" title="小试模板元编程"></a><p>很久不更新了，再水一下吧。</p>
<p>前两天新开的数据结构课布置上机作业，里面又出现了不知道之前出现过多少次的<a href="http://acm.buaa.edu.cn/oj/problem_show.php?c=99&amp;p=101330" target="_blank">输出质数</a>。每次都交表也会很乏味，所以……这次还是要交表 &#8211; -||| 不过要玩一点小花样——让编译器在编译期把质数表算出来。</p>
<p>这个当然涉及到一点<a href="http://zh.wikipedia.org/w/index.php?title=%E6%A8%A1%E6%9D%BF%E5%85%83%E7%B7%A8%E7%A8%8B&amp;variant=zh-cn" target="_blank">模板元编程</a>了。之前虽然看了《Effective C++》里关于模板元的简介挺感兴趣，但看到《<a href="http://blog.csdn.net/pongba/archive/2007/12/11/1930150.aspx" target="_blank">学习C++：实践者的方法</a>》里告诫不要在这种“20%场景下的复杂性”上白花时间<span style="color: #666666;">（“这些细节或技术在日常编程中极少用到，尤其是各种语言缺陷衍生出来的workarounds，构成了一个巨大的长尾……绝大多数只在库开发当中需要用到”）</span>，我一直对模板元编程敬而远之。这次也只是消遣一下，并无深入学习的打算。</p>
<p>以下是代码：</p>
<pre class="brush:c++">#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;iterator&gt;
#include &lt;algorithm&gt;

std::vector&lt;int&gt; Primes;

template &lt;int toTest, int factor&gt; // factor should be odd
class IsPrime
{
   public:
      enum {
         result = ( toTest == 2 )
         ||  toTest % factor
          &amp;&amp; IsPrime &lt; toTest , factor - 2 &gt;::result
      };
};

template&lt;int toTest&gt;
class IsPrime&lt;toTest, 1&gt;
{
   public:
      enum {result = ( toTest == 2 )  || ( toTest &amp; 1 ) };
};

template &lt;int upperBound&gt; // upperBound should be odd or 2
class PrimePick : public PrimePick &lt; upperBound - 2 &gt;
{
   public:
      enum {
         isPrime = IsPrime &lt; upperBound, ( upperBound &gt;&gt; 1 ) | 1 &gt;::result
      };
      PrimePick&lt;upperBound&gt;() {
         if ( isPrime )
            Primes.push_back ( upperBound );
      }
};

template&lt;&gt;
class PrimePick&lt;2&gt;
{
   public:
      PrimePick&lt;2&gt;() {
         Primes.push_back ( 2 );
      }
};

template&lt;&gt;
class PrimePick&lt;1&gt; : public PrimePick&lt;2&gt; {};

int main()
{
   PrimePick&lt;999&gt; PrimeInitializer;

   int m;
   std::cin &gt;&gt; m;
   for ( int i = 0; i &lt; m; ++i ) {
      int n;
      std::cin &gt;&gt; n;

      std::vector&lt;int&gt;::iterator end = Primes.begin();
      while ( end != Primes.end() &amp;&amp; *end &lt;= n )
         ++end;

      std::ostream_iterator&lt;int&gt; out ( std::cout, " " );
      std::copy ( Primes.begin(), end, out );
      std::cout &lt;&lt; std::endl;
   }
}
</pre>
<p>原理比较简单，主函数第一行初始化 PrimeInitializer 时，由于继承关系，构造函数会层层递归调用，从里至外利用另一个模板类 IsPrime 判断模板参数是否是质数，并把测试确认的质数放进一个 vector 里，这样就得到了编译期计算出的质数表。IsPrime 则使用最原始的试除方法判断质数。代码里一些写得很纠结的地方，一方面是为了尽量简化计算，减少编译时间，另一方面更主要是因为 g++ 默认最大只能实例化500层模板，以题目的数据规模（1000）不纠结一下编译器会抱怨。</p>
<p>这个程序……很不幸没能 AC。Buaa 的 OJ 在设计时估计就考虑了这种情况，对编译时间做出了限制，在编译20秒左右还没编译成功时会结束编译，直接判 <a href="http://acm.buaa.edu.cn/oj/status.php?problem_id=101330&amp;user_id=38211427&amp;result=-1&amp;c=99&amp;viewall=1" target="_blank">CE</a>……这个程序在我的系统上编译需要20分钟(VC 编译)到半个小时以上( g++ 编译)的时间，冬冬的64位 Ubuntu 上用 g++ 编译也需要将近10分钟时间。如果OJ不做这个限制估计会像当年vijos一样pending很多页吧……</p>
<p>恩，第一次模板元编程经历就以这样悲惨收场了 T_T</p>
<p>更新：</p>
<p>vijos<a href="http://fanfou.com/statuses/RNTyv6omdrE" target="_blank">果然被卡住了</a> &#8211; -</p>
<p><img class="alignnone" title="http://upload.tomtung.com/img/vijos-puppy-stuck.jpg" src="http://upload.tomtung.com/img/vijos-puppy-stuck.jpg" alt="http://upload.tomtung.com/img/vijos-puppy-stuck.jpg" width="621" height="505" /></p>
<p>可怜的puppy</p>
<p>已作为bug报告。</p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 84px; width: 1px; height: 1px; overflow: hidden;"><span style="font-family: monospace;"><span style="color: #a020f0;">#include</span> <span style="color: #ff00ff;">&lt;iostream&gt;</span><br />
<span style="color: #a020f0;">#include</span> <span style="color: #ff00ff;">&lt;vector&gt;</span><br />
<span style="color: #a020f0;">#include</span> <span style="color: #ff00ff;">&lt;iterator&gt;</span><br />
<span style="color: #a020f0;">#include</span> <span style="color: #ff00ff;">&lt;algorithm&gt;</span></p>
<p>std::vector&lt;<span style="color: #2e8b57;"><strong>int</strong></span>&gt; Primes;</p>
<p><span style="color: #2e8b57;"><strong>template</strong></span> &lt;<span style="color: #2e8b57;"><strong>int</strong></span> toTest, <span style="color: #2e8b57;"><strong>int</strong></span> factor&gt; <span style="color: #0000ff;">// factor should be odd</span><br />
<span style="color: #2e8b57;"><strong>class</strong></span> IsPrime<br />
{<br />
<span style="color: #804040;"><strong>public</strong></span>:<br />
<span style="color: #2e8b57;"><strong>enum</strong></span> {<br />
result = ( toTest == <span style="color: #ff00ff;">2</span> )<br />
||  toTest % factor<br />
&amp;&amp; IsPrime &lt; toTest , factor &#8211; <span style="color: #ff00ff;">2</span> &gt;::result<br />
};<br />
};</p>
<p><span style="color: #2e8b57;"><strong>template</strong></span>&lt;<span style="color: #2e8b57;"><strong>int</strong></span> toTest&gt;<br />
<span style="color: #2e8b57;"><strong>class</strong></span> IsPrime&lt;toTest, <span style="color: #ff00ff;">1</span>&gt;<br />
{<br />
<span style="color: #804040;"><strong>public</strong></span>:<br />
<span style="color: #2e8b57;"><strong>enum</strong></span> {result =  ( toTest == <span style="color: #ff00ff;">2</span> )  || ( toTest &amp; <span style="color: #ff00ff;">1</span> ) };<br />
};</p>
<p><span style="color: #2e8b57;"><strong>template</strong></span> &lt;<span style="color: #2e8b57;"><strong>int</strong></span> upperBound&gt; <span style="color: #0000ff;">// upperBound should be odd or 2</span><br />
<span style="color: #2e8b57;"><strong>class</strong></span> PrimePick : <span style="color: #804040;"><strong>public</strong></span> PrimePick &lt; upperBound &#8211; <span style="color: #ff00ff;">2</span> &gt;<br />
{<br />
<span style="color: #804040;"><strong>public</strong></span>:<br />
<span style="color: #2e8b57;"><strong>enum</strong></span> {<br />
isPrime = IsPrime &lt; upperBound, ( upperBound &gt;&gt; <span style="color: #ff00ff;">1</span> ) | <span style="color: #ff00ff;">1</span> &gt;::result<br />
};<br />
PrimePick&lt;upperBound&gt;() {<br />
<span style="color: #804040;"><strong>if</strong></span> ( isPrime )<br />
Primes.push_back (  upperBound );<br />
}<br />
};</p>
<p><span style="color: #2e8b57;"><strong>template</strong></span>&lt;&gt;<br />
<span style="color: #2e8b57;"><strong>class</strong></span> PrimePick&lt;<span style="color: #ff00ff;">2</span>&gt;<br />
{<br />
<span style="color: #804040;"><strong>public</strong></span>:<br />
PrimePick&lt;<span style="color: #ff00ff;">2</span>&gt;() {<br />
Primes.push_back ( <span style="color: #ff00ff;">2</span> );<br />
}<br />
};</p>
<p><span style="color: #2e8b57;"><strong>template</strong></span>&lt;&gt;<br />
<span style="color: #2e8b57;"><strong>class</strong></span> PrimePick&lt;<span style="color: #ff00ff;">1</span>&gt; : <span style="color: #804040;"><strong>public</strong></span> PrimePick&lt;<span style="color: #ff00ff;">2</span>&gt; {};</p>
<p><span style="color: #2e8b57;"><strong>int</strong></span> main()<br />
{<br />
PrimePick&lt;<span style="color: #ff00ff;">999</span>&gt; PrimeInitializer;</p>
<p><span style="color: #2e8b57;"><strong>int</strong></span> m;<br />
std::cin &gt;&gt; m;<br />
<span style="color: #804040;"><strong>for</strong></span> ( <span style="color: #2e8b57;"><strong>int</strong></span> i = <span style="color: #ff00ff;">0</span>;  i &lt; m; ++i ) {<br />
<span style="color: #2e8b57;"><strong>int</strong></span> n;<br />
std::cin &gt;&gt; n;</p>
<p>std::vector&lt;<span style="color: #2e8b57;"><strong>int</strong></span>&gt;::iterator end  = Primes.begin();<br />
<span style="color: #804040;"><strong>while</strong></span> ( end != Primes.end() &amp;&amp; *end &lt;= n )<br />
++end;</p>
<p>std::ostream_iterator&lt;<span style="color: #2e8b57;"><strong>int</strong></span>&gt; out ( std::cout, <span style="color: #ff00ff;">&#8221; &#8220;</span> );<br />
std::copy ( Primes.begin(), end, out );<br />
std::cout &lt;&lt; std::endl;<br />
}<br />
}</p>
<p></span></div>

<hr/><blockquote><p>可能你对下面的文章也感兴趣：</p><ol>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter2/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第二章'>C++ Primer 读书笔记 &#8211; 第二章</a></li>
<li><a href='http://blog.tomtung.com/2007/06/c-cpp-io-odd-behavior/' rel='bookmark' title='诡异的事：关于C/C++输入输出'>诡异的事：关于C/C++输入输出</a></li>
<li><a href='http://blog.tomtung.com/2008/09/cpp-primer-reding-notes-chapter8/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第八章'>C++ Primer 读书笔记 &#8211; 第八章</a></li>
</ol></blockquote>]]></content:encoded>
			<wfw:commentRss>http://blog.tomtung.com/2009/03/try-template-meta-programming/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>初来北航一个多月的零零碎碎</title>
		<link>http://blog.tomtung.com/2008/10/first-month-in-buaa/</link>
		<comments>http://blog.tomtung.com/2008/10/first-month-in-buaa/#comments</comments>
		<pubDate>Tue, 28 Oct 2008 16:19:15 +0000</pubDate>
		<dc:creator>逆铭</dc:creator>
				<category><![CDATA[生活在此处]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[北航]]></category>
		<category><![CDATA[巴赫]]></category>
		<category><![CDATA[开源]]></category>

		<guid isPermaLink="false">http://blog.tomtung.com/2008/10/%e5%88%9d%e6%9d%a5%e5%8c%97%e8%88%aa%e4%b8%80%e4%b8%aa%e5%a4%9a%e6%9c%88%e7%9a%84%e9%9b%b6%e9%9b%b6%e7%a2%8e%e7%a2%8e/</guid>
		<description><![CDATA[<a href="http://blog.tomtung.com/2008/10/first-month-in-buaa/" title="初来北航一个多月的零零碎碎"></a>几乎持续忙碌中。得空扯两句。 除了多了不少限制，生活和来之前差不多。食堂挺好。大运村很贵，不过想想也就4年而已，也就无所谓了。没阳台，很不方便。房间里有小强出没让人很不爽，不过比去年在福州一中见到的要小多了，也没那么嚣张。还好能有自己的书桌，用无线路由上着网，看着书，其实还是很惬意的。恩……我其实还是很容易满足的。 室友都很好很强大，让我觉得笨鸟先飞格外必要。有点后悔假期没有看看数学，现在一周五节数学（三节高数两节离散）让人有点吃不消。尤其是高数，大半年没有怎么做过这种题，现在看着它们感觉脑子像卡住了一样……英语依旧荒废中，腾不出手来处理，所幸 RP 足够好进了 B 班。专业方面，终于还是失去了第二遍读完 C++ Primer 的耐心，这份读书笔记也不知何年何月才能完成了。转而开始看 Effective C++，看完那三本 Effective 就不再在 C++ 上过多纠缠了，什么模板元之类的都省省吧……这门语言的复杂程度已经足够让我望而却步了，抱着厚书啃啊啃也啃不完总不是办法，还是今后在实践中逐渐积累吧。《Pro C# with .NET 3.0 Special Edition》刚到第八章，《Head First Design Patterns》也到第八章。它们的阅读进度都由于要顾及数学被严重拖慢了，很让人郁闷。至于其它七七八八的科目，什么语文啊计算机导论啊历史啊政治啊航空航天概论啊，都在摸着石头瞎混中，但愿能混过去…… 没参加任何类似学生会或者班委会的组织。社团仅仅参加了 MSTC（微软技术俱乐部），并且顺利混进 .NET 组。据冬冬说，我在面试时极为成功的装X竟然让某巨牛印象深刻并颇为赞许，这让我相当有成就感。如果顺利，不太久会参与项目开发。看来我放假时决定学 C# 还算明智。现在感觉 MSTC 还算不错。 本来准备参加的 GC（Google Camp）也顺利入围技术部，不过了解更多以后觉得很不靠谱，暂且退出免得浪费时间。 ACM/ICPC 终于还是没有去参加……恩，连新生的选拔赛都干脆没去。虽然这个决定是早在年初就做好的，心中还是免不了一丝不舍。希望我没有做出错误的选择。 之前参加了一次 Liunx &#8230;<p class="read-more"><a href="http://blog.tomtung.com/2008/10/first-month-in-buaa/">继续阅读 &#187;</a></p><hr/><blockquote>
可能你对下面的文章也感兴趣：<ol>
<li><a href='http://blog.tomtung.com/2008/09/unable-to-stay/' rel='bookmark' title='写在临行前'>写在临行前</a></li>
<li><a href='http://blog.tomtung.com/2008/07/letter-of-admission-from-buaa/' rel='bookmark' title='保送的最终结果'>保送的最终结果</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter7/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第七章'>C++ Primer 读书笔记 &#8211; 第七章</a></li>
</ol></blockquote>]]></description>
			<content:encoded><![CDATA[<a href="http://blog.tomtung.com/2008/10/first-month-in-buaa/" title="初来北航一个多月的零零碎碎"></a><p><img class="alignnone" title="http://upload.tomtung.com/img/reminder_look_at_reminder_wall.jpg" src="http://upload.tomtung.com/img/reminder_look_at_reminder_wall.jpg" alt="http://upload.tomtung.com/img/reminder_look_at_reminder_wall.jpg" width="480" height="398" /></p>
<p>几乎持续忙碌中。得空扯两句。</p>
<p>除了多了不少限制，生活和来之前差不多。食堂挺好。大运村很贵，不过想想也就4年而已，也就无所谓了。没阳台，很不方便。房间里有小强出没让人很不爽，不过比去年在福州一中见到的要小多了，也没那么嚣张。还好能有自己的书桌，用无线路由上着网，看着书，其实还是很惬意的。恩……我其实还是很容易满足的。</p>
<p style="text-align: center;"><a href="http://upload.tomtung.com/img/my_desk.jpg"><img class="aligncenter" title="http://upload.tomtung.com/img/my_desk.jpg" src="http://upload.tomtung.com/img/my_desk.jpg" alt="" width="625" height="470" /></a></p>
<p>室友都很好很强大，让我觉得笨鸟先飞格外必要。有点后悔假期没有看看数学，现在一周五节数学（三节高数两节离散）让人有点吃不消。尤其是高数，大半年没有怎么做过这种题，现在看着它们感觉脑子像卡住了一样……英语依旧荒废中，腾不出手来处理，所幸 RP 足够好进了 B 班。专业方面，终于还是失去了第二遍读完 C++ Primer 的耐心，这份<a href="http://blog.sina.com.cn/s/blog_4a443fd70100aq4s.html" target="_blank">读书笔记</a>也不知何年何月才能完成了。转而开始看 Effective C++，看完那三本 Effective 就不再在 C++ 上过多纠缠了，什么模板元之类的都省省吧……这门语言的复杂程度已经足够让我望而却步了，抱着厚书啃啊啃也啃不完总不是办法，还是今后在实践中逐渐积累吧。《<a href="http://www.douban.com/subject/2995420/" target="_blank">Pro C# with .NET 3.0 Special Edition</a>》刚到第八章，《<a href="http://www.douban.com/subject/1400656/" target="_blank">Head First Design Patterns</a>》也到第八章。它们的阅读进度都由于要顾及数学被严重拖慢了，很让人郁闷。至于其它七七八八的科目，什么语文啊计算机导论啊历史啊政治啊航空航天概论啊，都在摸着石头瞎混中，但愿能混过去……</p>
<p>没参加任何类似学生会或者班委会的组织。社团仅仅参加了 MSTC（微软技术俱乐部），并且顺利混进 .NET 组。据冬冬说，我在面试时极为成功的装X竟然让某巨牛印象深刻并颇为赞许，这让我相当有成就感。如果顺利，不太久会参与项目开发。看来我放假时决定学 C# 还算明智。现在感觉 MSTC 还算不错。</p>
<p>本来准备参加的 GC（Google Camp）也顺利入围技术部，不过了解更多以后觉得很不靠谱，暂且退出免得浪费时间。</p>
<p>ACM/ICPC 终于还是没有去参加……恩，连新生的选拔赛都干脆没去。虽然这个决定是早在年初就做好的，心中还是免不了一丝不舍。希望我没有做出错误的选择。</p>
<p><img class="alignnone" title="http://upload.tomtung.com/img/gnome-asia-08.jpg" src="http://upload.tomtung.com/img/gnome-asia-08.jpg" alt="" width="270" height="96" /></p>
<p><img src="http://gnome.asia/static/img/gnome.asia-logo-2008.21.96px.2.png" alt="" /></p>
<p>之前参加了一次 <a href="http://www.douban.com/event/10284206/" target="_blank">Liunx of BUAA 北航小聚</a>，用 Vista 的我只能拿本里的 <a href="http://www.andlinux.org/" target="_blank">andLinux </a>充数。群牛闪耀，气氛很融洽，更重要的是我和冬冬很幸运地遇到 <a href="http://www.douban.com/people/2988178/" target="_blank">Jesse</a>，他是在北航举行的08年 <a href="http://www.douban.com/event/10247550/" target="_blank">Gnome 亚洲峰会</a>（<a href="http://gnome.asia/" target="_blank">主页</a>）北航方面的负责人，然后我们就高高兴兴地成了志愿者。记得是蒋天正还是谁给我们说，你们刚来没几天就能参加国际会议了~~ 作为技术上太水的人，我也就只能搬搬桌子、指个路什么的，以此为开源社区做点贡献了。顺带一提，这样一个技术会议的组织者竟然是 Emily 姐和 Pockey 姐两位女性，真是奇妙。会议很成功，<a href="http://flickr.com/search/?w=all&amp;q=gnomeasia&amp;m=text" target="_blank">这里</a>有n多大家拍的照片。以此为契机，北航的开源社团似乎也即将成立，真是件好事。</p>
<p><img class="alignnone" title="http://upload.tomtung.com/img/starker-bach-solo-cello-suites.jpg" src="http://upload.tomtung.com/img/starker-bach-solo-cello-suites.jpg" alt="" width="499" height="472" /></p>
<p>一段时间听了很多碟。周董的新专辑还不如上一张，周导演果然没时间玩音乐了；JJ的新专辑安排很杂，不过整体质量还算不错。重新开始听原来没什么感觉的门德尔松无词歌。又开始迷巴赫，重听了以前没有特别留心感受的曲子，从大无开始，到小无，然后是钢琴的帕提塔、意大利协奏曲等等，并且各同时找好几个版本对照。上课路上看着阳光透过教学区树木的树冠，随着欢欣的库兰特舞跳动，或者眯起眼睛依着一首萨拉班德打一会儿瞌睡，觉得生活真是美好。托卡塔从耳旁流过时似乎可以提神，严谨紧凑的赋格似乎也会潜移默化地帮助思考。温暖且踏实的大调诠释着幸福，清冷或宁静的小调表达着自省，二者交替间很容易就在我的心室中共鸣回响起来。从不滥情的巴赫总能让人在忙碌中保持安稳，我每过一段时间似乎都会到巴赫这里停靠。每次少则一周多则一两个月，总能得到珍贵的体验。</p>
<p>恩……似乎这段时间值得说的就是这么多。瞎忙之中一切看起来都在向着好的方向发展，一些小麻烦还不足以影响心情。希望一切顺利。</p>
<p>最后，祝贺银男 Ghost 终于银了。祝高三各位大牛保送顺利。欢迎报考 BUAA。</p>

<hr/><blockquote><p>可能你对下面的文章也感兴趣：</p><ol>
<li><a href='http://blog.tomtung.com/2008/09/unable-to-stay/' rel='bookmark' title='写在临行前'>写在临行前</a></li>
<li><a href='http://blog.tomtung.com/2008/07/letter-of-admission-from-buaa/' rel='bookmark' title='保送的最终结果'>保送的最终结果</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter7/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第七章'>C++ Primer 读书笔记 &#8211; 第七章</a></li>
</ol></blockquote>]]></content:encoded>
			<wfw:commentRss>http://blog.tomtung.com/2008/10/first-month-in-buaa/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>写在临行前</title>
		<link>http://blog.tomtung.com/2008/09/unable-to-stay/</link>
		<comments>http://blog.tomtung.com/2008/09/unable-to-stay/#comments</comments>
		<pubDate>Thu, 18 Sep 2008 09:27:00 +0000</pubDate>
		<dc:creator>逆铭</dc:creator>
				<category><![CDATA[生活在此处]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[北航]]></category>
		<category><![CDATA[英语]]></category>
		<category><![CDATA[钢琴]]></category>

		<guid isPermaLink="false">http://blog.tomtung.com/2008/09/%e5%86%99%e5%9c%a8%e4%b8%b4%e8%a1%8c%e5%89%8d/</guid>
		<description><![CDATA[<a href="http://blog.tomtung.com/2008/09/unable-to-stay/" title="写在临行前"></a>昨天终于顺利闹完了，20号开学，今晚的火车，明天到。 如果从年初学校定下来开始算起，到现在，那真是有大半年的假期了。虽然基本上一直都是忙忙碌碌的，但是效率并不咋高。假期开始的时候没写什么假期计划，现在就写点总结吧。 E文的重要性我是清楚的，自己清楚确实需要加强。原来有人（好吧，我坦白，包括我自己）觉得我英语不错，其实现在客观地看，不过是几句简单的说得比较溜，能吓唬下不了解情况的人而已，其实在基础各方面问题非常多。 我差不多是从今年4月份开始重新拾起E文的。兰州找不到合适的班，就自己跟着一个叫《彭蒙惠英语》的杂志走。这个是空中英语教室系列的高级版，对我来说比较吃力，但是中级版又太EZ，只好勉强用这本，结果每个月甚至都没有精力看完当月的内容。4~8月读过的课文篇数分别为2、6、7、8、1，可见利用率并不高。 当初其实规划得挺好：每天都安排课文和配套广播，可以练阅读和听力；遇到的生词记下来可以提升词汇量；另外还在网上找到了语音讨论组可以练习口语。这样就可以全面提高了。但是对我来说杂志内容难度实在偏大，每天都要花费不少时间。每天如果读课文至少需要半小时，预习半小时，广播节目半小时。口语练习一小时。生词仅一共背了 2000左右（更不幸的是现在已经忘掉不少了），难度等级从小学初中到专八GRE都有（可见我野路子学上来的基础确实有问题），每天按照软件安排复习和初记至少半小时。这样算下来单单是英文每天就要最少花费3小时，哪天稍微耽搁后面进度就跟不上了，煞是郁闷，到最后就干脆坚持不下来了。现在还是没有真正找到合适的英语学习方法，比较愁，哪位同学有什么建议欢迎在下面评论。 数学看得不多，除去已经忘掉的就可以忽略不计了…… 专业课方面，主要是看完了一本C#和对象建模的入门书，以及C++ Primer。前者非常基础，需要深入起码还要看好几本。后者，正如我在这里所说的，花了超出预期很多的时间才看完第一遍，第二遍也没能在开学前看完。本来原计划是在开学前不但看完Primer，还要看完那三本Effective的，彻底搞定明年新标准发布前我需要掌握的C++内容。已经完成的部分和计划相比差太多了。 学会了游泳。 自学一点钢琴，教材用599和哈农，从高考开始学到现在，各只弹到第15首。买的琴是Yamaha DGX-620，本来想带去学校继续学的，结果发现我根本没有理解20公斤意味着什么……况且宿舍小也不一定能放得下。原来所谓Portable Grand的意思仅仅是相对Grand稍微Portable 一点而已了。查了下其它的电钢，似乎真正比较Portable的键盘都不带配重……那就先算了吧。 恩……大致就是以上这些了。Linda姐问我假期最大的成果是什么，我说不知道……各项都不满意。忙忙碌碌但不出效果。其实把C++和E文放在一起的安排是很失败的，一天到晚都在看语言上拉拉杂杂的东西，搞得人又烦又低效。。。 忙忙碌碌的，看起来那么长的一个假期也就这样过去了。昨天去一中，见了老赵、DF、野牛、格格他们，又在楼道里习惯性闲逛，在二球下习惯性驻足，在公交站台上习惯性无意义等待。即将满载着回忆离开，除了少了很多熟识的面孔，那里的一切都还是一样熟悉。 之前同学陆陆续续都走差不多了，并没有太多离别的伤感。我只是觉得大家保持着联系就好，有缘也肯定还会再见。我似乎总是习惯看好现在，看好将来，并不太多留恋身后。想想旅行时我不喜欢拍很多照片留念可能也是这个原因吧。是豁达，是冷漠，还是不知珍惜，我自己无从分辨。我一直自以为是前者，只是昨天从姥姥家回来才产生了怀疑。 姥姥快八十岁了，坚持要在我走之前看看我。她对我絮絮叨叨了很多已经说过很多遍的事情，然后让我常给她打电话。我们都笑着说姥姥拿起电话就豆腐三碗、三碗豆腐说个没完没了了，长途话费下来肯定把人愁死。姥姥摇着头说，她知道长途花费贵，又说我学习紧张，又说宿舍里那么多人也影响别人，只要我每周周末晚上打个电话就行了，她就和我说一句话，就一句，说好着呢，听听我的声音马上就挂掉……一边说用手掌抹着已经发红的眼眶。我们赶紧解释说长途花费是按时间计的，没有那么贵，学习也并没有那么紧张，也不会打扰到别人。姥姥还是摇着头说没事的时候多休息不要打电话，每周打一次电话，说一句话听听我的声音就行了，就一句话就行了……絮叨地这么说了很多遍。 我有些不知所措，突然间感到亲人对自己如此强烈的不舍。看着姥姥发红的双眼，我突然觉得不忍离去。这是一种我其实一直没有真正明白的情感，曾经很多老师对此的解释都是“等你们做父母、祖父母了就明白了”。作为一个自私的独生子女，我想我并没有真正懂得什么是爱。 我只是愣在那里，不断提醒自己记得多打几个电话。除此之外我不知道还能做到什么。 Unable To Stay, Unwilling To Leave. 不管怎样，几天以后就是完全不同的生活了。 ﻿ 可能你对下面的文章也感兴趣： 保送的最终结果 C++ Primer 读书笔记 &#8211; 第六章 C++ Primer 读书笔记 &#8211; 索引<hr/><blockquote>
可能你对下面的文章也感兴趣：<ol>
<li><a href='http://blog.tomtung.com/2008/07/letter-of-admission-from-buaa/' rel='bookmark' title='保送的最终结果'>保送的最终结果</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter6/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第六章'>C++ Primer 读书笔记 &#8211; 第六章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-index/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 索引'>C++ Primer 读书笔记 &#8211; 索引</a></li>
</ol></blockquote>]]></description>
			<content:encoded><![CDATA[<a href="http://blog.tomtung.com/2008/09/unable-to-stay/" title="写在临行前"></a><p>昨天终于顺利闹完了，20号开学，今晚的火车，明天到。</p>
<p>如果从年初学校定下来开始算起，到现在，那真是有大半年的假期了。虽然基本上一直都是忙忙碌碌的，但是效率并不咋高。假期开始的时候没写什么假期计划，现在就写点总结吧。</p>
<p>E文的重要性我是清楚的，自己清楚确实需要加强。原来有人（好吧，我坦白，包括我自己）觉得我英语不错，其实现在客观地看，不过是几句简单的说得比较溜，能吓唬下不了解情况的人而已，其实在基础各方面问题非常多。</p>
<p>我差不多是从今年4月份开始重新拾起E文的。兰州找不到合适的班，就自己跟着一个叫《彭蒙惠英语》的杂志走。这个是空中英语教室系列的高级版，对我来说比较吃力，但是中级版又太EZ，只好勉强用这本，结果每个月甚至都没有精力看完当月的内容。4~8月读过的课文篇数分别为2、6、7、8、1，可见利用率并不高。</p>
<p>当初其实规划得挺好：每天都安排课文和配套广播，可以练阅读和听力；遇到的生词记下来可以提升词汇量；另外还在网上找到了<a href="http://bulo.hjenglish.com/group/advanced/" target="_blank">语音讨论组</a>可以练习口语。这样就可以全面提高了。但是对我来说杂志内容难度实在偏大，每天都要花费不少时间。每天如果读课文至少需要半小时，预习半小时，广播节目半小时。口语练习一小时。生词仅一共背了 2000左右（更不幸的是现在已经忘掉不少了），难度等级从小学初中到专八GRE都有（可见我野路子学上来的基础确实有问题），每天按照软件安排复习和初记至少半小时。这样算下来单单是英文每天就要最少花费3小时，哪天稍微耽搁后面进度就跟不上了，煞是郁闷，到最后就干脆坚持不下来了。现在还是没有真正找到合适的英语学习方法，比较愁，哪位同学有什么建议欢迎在下面评论。</p>
<p>数学看得不多，除去已经忘掉的就可以忽略不计了……</p>
<p>专业课方面，主要是看完了<a href="http://www.douban.com/subject/1845269/" target="_blank">一本C#和对象建模的入门书</a>，以及C++ Primer。前者非常基础，需要深入起码还要看好几本。后者，正如我在<a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-index/">这里</a>所说的，花了超出预期很多的时间才看完第一遍，第二遍也没能在开学前看完。本来原计划是在开学前不但看完Primer，还要看完那三本Effective的，彻底搞定明年新标准发布前我需要掌握的C++内容。已经完成的部分和计划相比差太多了。</p>
<p>学会了游泳。</p>
<p>自学一点钢琴，教材用599和哈农，从高考开始学到现在，各只弹到第15首。买的琴是Yamaha DGX-620，本来想带去学校继续学的，结果发现我根本没有理解20公斤意味着什么……况且宿舍小也不一定能放得下。原来所谓Portable Grand的意思仅仅是相对Grand稍微Portable 一点而已了。查了下其它的电钢，似乎真正比较Portable的键盘都不带配重……那就先算了吧。</p>
<p>恩……大致就是以上这些了。Linda姐问我假期最大的成果是什么，我说不知道……各项都不满意。忙忙碌碌但不出效果。其实把C++和E文放在一起的安排是很失败的，一天到晚都在看语言上拉拉杂杂的东西，搞得人又烦又低效。。。</p>
<p>忙忙碌碌的，看起来那么长的一个假期也就这样过去了。昨天去一中，见了老赵、DF、野牛、格格他们，又在楼道里习惯性闲逛，在二球下习惯性驻足，在公交站台上习惯性无意义<a href="http://fanfou.com/statuses/Msxzgfz5jHM" target="_blank">等待</a>。即将满载着回忆离开，除了少了很多熟识的面孔，那里的一切都还是一样熟悉。</p>
<p>之前同学陆陆续续都走差不多了，并没有太多离别的伤感。我只是觉得大家保持着联系就好，有缘也肯定还会再见。我似乎总是习惯看好现在，看好将来，并不太多留恋身后。想想旅行时我不喜欢拍很多照片留念可能也是这个原因吧。是豁达，是冷漠，还是不知珍惜，我自己无从分辨。我一直自以为是前者，只是昨天从姥姥家回来才产生了怀疑。</p>
<p>姥姥快八十岁了，坚持要在我走之前看看我。她对我絮絮叨叨了很多已经说过很多遍的事情，然后让我常给她打电话。我们都笑着说姥姥拿起电话就豆腐三碗、三碗豆腐说个没完没了了，长途话费下来肯定把人愁死。姥姥摇着头说，她知道长途花费贵，又说我学习紧张，又说宿舍里那么多人也影响别人，只要我每周周末晚上打个电话就行了，她就和我说一句话，就一句，说好着呢，听听我的声音马上就挂掉……一边说用手掌抹着已经发红的眼眶。我们赶紧解释说长途花费是按时间计的，没有那么贵，学习也并没有那么紧张，也不会打扰到别人。姥姥还是摇着头说没事的时候多休息不要打电话，每周打一次电话，说一句话听听我的声音就行了，就一句话就行了……絮叨地这么说了很多遍。</p>
<p>我有些不知所措，突然间感到亲人对自己如此强烈的不舍。看着姥姥发红的双眼，我突然觉得不忍离去。这是一种我其实一直没有真正明白的情感，曾经很多老师对此的解释都是“等你们做父母、祖父母了就明白了”。作为一个自私的独生子女，我想我并没有真正懂得什么是爱。</p>
<p>我只是愣在那里，不断提醒自己记得多打几个电话。除此之外我不知道还能做到什么。</p>
<p>Unable To Stay, Unwilling To Leave. 不管怎样，几天以后就是完全不同的生活了。<br />
﻿</p>

<hr/><blockquote><p>可能你对下面的文章也感兴趣：</p><ol>
<li><a href='http://blog.tomtung.com/2008/07/letter-of-admission-from-buaa/' rel='bookmark' title='保送的最终结果'>保送的最终结果</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter6/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第六章'>C++ Primer 读书笔记 &#8211; 第六章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-index/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 索引'>C++ Primer 读书笔记 &#8211; 索引</a></li>
</ol></blockquote>]]></content:encoded>
			<wfw:commentRss>http://blog.tomtung.com/2008/09/unable-to-stay/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>C++ Primer 读书笔记 &#8211; 第八章</title>
		<link>http://blog.tomtung.com/2008/09/cpp-primer-reding-notes-chapter8/</link>
		<comments>http://blog.tomtung.com/2008/09/cpp-primer-reding-notes-chapter8/#comments</comments>
		<pubDate>Tue, 02 Sep 2008 07:12:15 +0000</pubDate>
		<dc:creator>逆铭</dc:creator>
				<category><![CDATA[新长征路上的代码]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[笔记]]></category>

		<guid isPermaLink="false">http://blog.tomtung.com/2008/09/c-primer-%e8%af%bb%e4%b9%a6%e7%ac%94%e8%ae%b0-%e7%ac%ac%e5%85%ab%e7%ab%a0/</guid>
		<description><![CDATA[<a href="http://blog.tomtung.com/2008/09/cpp-primer-reding-notes-chapter8/" title="C++ Primer 读书笔记 - 第八章"></a>[笔记索引] 第８章 标准IO库 ⒈ IO标准库类型 类名           派生自            头文件       描述 istream        ios               iostream   输入流 ostream        ios               iostream   输出流 iostream       istream和ostream  iostream   输入/输出流 ifstream       istream           fstream    输入文件流 ofstream       ostream           fstream    输出文件流 fstream        iostream          fstream    输入/输出文件流 istringstream  istream           sstream    输入字符串流 ostringstream  ostream           sstream    输出字符串流 stringstream   iostream          sstream    输入/输出字符串流 ⑴ 标准库分别实现了以上继承层次的的两个版本，分别面向 char 类型（如上）和 wchar_t 类型 后者采用和前者一样的命名规则，仅在每个类和对象名前加上字母w以示区别 ⑵ IO对象不可赋值或赋值 ⒉ &#8230;<p class="read-more"><a href="http://blog.tomtung.com/2008/09/cpp-primer-reding-notes-chapter8/">继续阅读 &#187;</a></p><hr/><blockquote>
可能你对下面的文章也感兴趣：<ol>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter4/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第四章'>C++ Primer 读书笔记 &#8211; 第四章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter2/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第二章'>C++ Primer 读书笔记 &#8211; 第二章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter5/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第五章'>C++ Primer 读书笔记 &#8211; 第五章</a></li>
</ol></blockquote>]]></description>
			<content:encoded><![CDATA[<a href="http://blog.tomtung.com/2008/09/cpp-primer-reding-notes-chapter8/" title="C++ Primer 读书笔记 - 第八章"></a><p style="text-align: right;"><a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-index/" target="_blank"><span style="font-size: 12px;"> [笔记索引]</span></a></p>
<p><span style="font-size: 12px;">第８章 标准IO库</span></p>
<p><span style="font-size: 12px;"> ⒈ IO标准库类型<br />
类名           派生自            头文件       描述<br />
istream        ios               iostream   输入流<br />
ostream        ios               iostream   输出流<br />
iostream       istream和ostream  iostream   输入/输出流<br />
ifstream       istream           fstream    输入文件流<br />
ofstream       ostream           fstream    输出文件流<br />
fstream        iostream          fstream    输入/输出文件流<br />
istringstream  istream           sstream    输入字符串流<br />
ostringstream  ostream           sstream    输出字符串流<br />
stringstream   iostream          sstream    输入/输出字符串流</span></p>
<p><span style="font-size: 12px;"> ⑴ 标准库分别实现了以上继承层次的的两个版本，分别面向 </span><span style="color: #2e8b57;"><strong>char</strong></span> 类型（如上）和 <span style="color: #2e8b57;"><strong>wchar_t</strong></span> 类型<br />
后者采用和前者一样的命名规则，仅在每个类和对象名前加上字母w以示区别<br />
⑵ IO对象不可赋值或赋值</p>
<p>⒉ 标准输入输出对象<br />
<span style="color: #2e8b57;"><strong>extern</strong></span> istream cin; 标准输入流<br />
<span style="color: #2e8b57;"><strong>extern</strong></span> ostream cout; 标准输出流<br />
<span style="color: #2e8b57;"><strong>extern</strong></span> ostream cerr;  标准错误输出流<br />
<span style="color: #2e8b57;"><strong>extern</strong></span> ostream clog; 标准日志输出流</p>
<p>⒊ 文件输入输出流<br />
⑴ 使用 ifstream, ofstream 和 fstream 型对象可以实现对文件的读写<br />
⑵ 可以调用公共成员函数 open 或在创建时使用构造函数使流对象关联到一个文件<br />
二者都接受两个参数：一个C风格字符串表示文件名，一个可选的 ios_base::openmode 型值表示流打开模式<br />
① openmode 是用以表示流打开模式标识的位掩码类型，支持位操作符<br />
该类型对象的值可以是以下打开模式标识或它们之间进行位操作所得的结果<br />
和以下(openmode 型)模式标志均为 ios_base 的公共成员<br />
Ⅰ app (append)每次执行输出操作前都定位到流的末尾<br />
Ⅱ ate (at end)打开时定位到流末尾<br />
Ⅲ binary 在二进制(而非文本)模式下操作<br />
Ⅳ in (input)允许输入操作<br />
Ⅴ out (output)允许输出操作<br />
Ⅵ trunc (truncate)抛弃流中现存的所有内容，打开时假定长度为<span style="color: #ff00ff;">0</span><br />
(openmode 和上述标识分别是 ios_base 的公共成员类型和公共成员常量)<br />
② fstream 默认使用 in | out 模式<br />
ifstream 自动使用 in 模式<br />
ofstream 自动使用 out 模式(效果上等同于 out | trunc)<br />
⑶ 完成文件操作后可以使用公共成员函数 <span style="color: #2e8b57;"><strong>void</strong></span> close() 关闭<br />
关闭后可以再次 open 新文件，但之前应调用 clear 清除该流的状态<br />
流对象被析构时也会自动调用 close()</p>
<p>⒋ 字符串流<br />
⑴ 常用于特定数据类型和格式化的字符串之间的相互转换<br />
⑵ <span style="color: #ff00ff;">3</span>个类的构造函数各有带或不带 string 形参的两个不同版本<br />
使用带 string 参数的版本，则创建储存该实参副本的字符串流对象<br />
⑶ <span style="color: #ff00ff;">3</span>个类的都有公共成员函数 str，它的两个版本分别返回和设置与该流对象相关的 string 对象<br />
string str() <span style="color: #2e8b57;"><strong>const</strong></span>;<br />
返回与该流对象相关的 string 对象<br />
string str(<span style="color: #2e8b57;"><strong>const</strong></span> string&amp;);<br />
将该流对象相关的 string 对象设置为实参的副本</p>
<p>⒌ 条件状态<br />
⑴ 流对象内都用一个 iostate 型值表示条件状态<br />
· iostate 是用以表示流错误状态标志的位掩码类型，支持位操作符<br />
该类型对象的值可以是以下条件状态标识或它们之间进行位操作所得的结果<br />
Ⅰ eofbit 输入操作中遇到文件结束符(同时会设置failbit)<br />
Ⅱ failbit 输入操作失败(通常可恢复)<br />
Ⅲ badbit 流被损坏(通常不可恢复)<br />
Ⅳ goodbit 没有错误，值为<span style="color: #ff00ff;">0</span><br />
(iostate 和上述标识分别是 ios_base 的公共成员类型和公共成员常量)<br />
⑵ 查询条件状态<br />
<span style="color: #2e8b57;"><strong>bool</strong></span> ios::eof() <span style="color: #2e8b57;"><strong>const</strong></span>;<br />
eofbit位被设置则返回 <span style="color: #ff00ff;">true</span>, 否则返回 <span style="color: #ff00ff;">false</span><br />
<span style="color: #2e8b57;"><strong>bool</strong></span> ios::fail() <span style="color: #2e8b57;"><strong>const</strong></span>;<br />
failbit 或 badbit 位被设置则返回 <span style="color: #ff00ff;">true</span>, 否则返回 <span style="color: #ff00ff;">false</span><br />
<span style="color: #2e8b57;"><strong>bool</strong></span> ios::bad() <span style="color: #2e8b57;"><strong>const</strong></span>;<br />
badbit 位被设置则返回 <span style="color: #ff00ff;">true</span>, 否则返回 <span style="color: #ff00ff;">false</span><br />
<span style="color: #2e8b57;"><strong>bool</strong></span> ios::good() <span style="color: #2e8b57;"><strong>const</strong></span>;<br />
流对象有效则返回 <span style="color: #ff00ff;">true</span>, 否则返回 <span style="color: #ff00ff;">false</span><br />
ios_base::iostate rdstate() <span style="color: #2e8b57;"><strong>const</strong></span>;<br />
返回当前条件状态<br />
⑶ 控制条件状态<br />
<span style="color: #2e8b57;"><strong>void</strong></span> ios::clear( ios_base::iostate = goodbit);<br />
使用参数值替换当前条件状态<br />
<span style="color: #2e8b57;"><strong>void</strong></span> ios::setstate( ios_base::iostate );<br />
将参数状态加入当前状态(如同使用了位或操作符|)<br />
⑷ 可以直接检查流对象的真值来确认是否可用</p>
<p>⒍ 输出缓冲区的管理<br />
每个IO对象都管理一个缓冲区，作为流和写入目标间的媒介<br />
下面几种情况将导致输出流被刷新(即写入到真实的输出设备或者文件)<br />
⑴ 程序正常结束或目标文件被关闭<br />
注: 程序崩溃不会刷新缓冲区<br />
调试崩溃的程序时如果用最后的输出定义错误位置，应确保缓冲区已刷新<br />
因此输出时应多使用endl而非<span style="color: #6a5acd;">&#8216;\n&#8217;</span><br />
⑵ 当缓冲区满时会自动刷新<br />
⑶ 使用操纵符显式刷新缓冲区<br />
(以下均定义在&lt;ostream&gt;中)<br />
① endl 输出换行符并刷新缓冲区<br />
② flush 刷新缓冲区(不添加任何字符)<br />
③ ends 输出空字符<span style="color: #6a5acd;">&#8216;\0&#8242;</span>并刷新缓冲区<br />
注：cplusplus.com,cppreference.com和msdn上都没有表示ends会刷新缓冲区，存疑<br />
⑷ 使用 unitbuf 操纵符可以设置流对象的相关格式状态标志，使缓冲区在每次插入操作后都刷新<br />
使用 nounitbuf 操纵符可以恢复为正常的、系统控制的缓冲区刷新方式<br />
⑸ 可以把流对象绑定到一个输出流对象，前者进行任何I/O操作都会刷新后者<br />
① 可以使用 ios::tie 公共成员函数查询、修改绑定状态<br />
ostream* ios::tie() <span style="color: #2e8b57;"><strong>const</strong></span>;<br />
返回指向所绑定到的输出流对象的指针<br />
ostream* ios::tie( ostream* );<br />
绑定到参数中指针指向的输出流对象(实参为<span style="color: #ff00ff;">0</span>则解除绑定)，并返回指向原绑定对象的指针<br />
② cin, cerr, clog 默认绑定到 cout, 而它们的宽字符版本则默认绑定到 wcout</p>
<p>⒎ 控制格式状态<br />
istream/ostream(及它们的派生类)对象都支持使用提取操作符(&gt;&gt;)/插入操作符(&lt;&lt;)，从流中提取/向流中插入格式化的对象数据<br />
把提取/插入操作符和一些操纵符(manipulator)一起使用，可以改变流对象的特性或格式设置<br />
其中除setbase,setprecision,setw,setfill定义在头文件&lt;iomanip&gt;中外，其余操纵符均定义在&lt;ios&gt;中<br />
⑴ 布尔值格式<br />
从流中提取/向流中插入布尔值时形式使用 <span style="color: #ff00ff;">0</span>, <span style="color: #ff00ff;">1</span>(默认) 还是 <span style="color: #ff00ff;">false</span>, <span style="color: #ff00ff;">true</span><br />
· 使用操纵符 boolalpha noboolalpha<br />
⑵ 整数格式<br />
① 基数设置<br />
从流中提取/向流中插入整数时使用八进制、十进制(默认)还是十六进制<br />
· 使用操纵符 oct dec hex<br />
· 使用操纵符 setbase(<span style="color: #2e8b57;"><strong>int</strong></span>) (实参只能是<span style="color: #ff00ff;">8</span>,<span style="color: #ff00ff;">10</span>或<span style="color: #ff00ff;">16</span>)<br />
② 基数前缀设置<br />
向流中插入整数时是否显示基数前缀(八进制的<span style="color: #ff00ff;">0</span>和十六进制的0x)(默认不显示)<br />
· 使用操纵符 showbase noshowbase<br />
③ 十六进制和科学计数法中字母的大小写设置<br />
向流中插入整数时若使用十六进制或科学计数法，出现的字母使用小写(默认)还是大写<br />
· 使用操纵符 uppercase nouppercase<br />
⑶ 浮点数格式<br />
① 精度设置<br />
向流中插入浮点数精度为多少(默认为<span style="color: #ff00ff;">6</span>)<br />
· 使用 ios_base 的公共成员函数 precision 可以获得和设置流的浮点数精度<br />
streamsize precision() <span style="color: #2e8b57;"><strong>const</strong></span>;<br />
返回流对象的浮点数精度<br />
streamsize precision( streamsize );<br />
设置流的浮点数精度为实参值并返回先前的精度值<br />
· 使用操纵符 setprecision( streamsize )<br />
以上 streamsize 为表示流中大小的实现类型，是一个带符号基本整型的别名<br />
注: 精度的解释在使用不同情况下不同<br />
· 默认情况下解释为最大有效数字(位数不足不用小数末尾的零补齐)<br />
· 在强制使用fixed,scientific或showpoint时解释为小数点后的确切位数(位数不足则用小数末尾的零补齐)<br />
② 计数法设置<br />
向流中插入浮点数时，让系统自动选择计数法(默认)，还是强制指定为定点计数法或科学计数法<br />
· 使用操纵符 fixed scientific<br />
· 计数法不存在恢复默认的操纵符，但可以通过给成员函数 unsetf 传入常量 floatfield 达到目的<br />
(unsetf 和 floatfield 均为 ios_base 的公共成员)<br />
③ 小数点显示设置<br />
向流中插入浮点数时，若小数部分为<span style="color: #ff00ff;">0</span>，是否显示小数点和小数部分的<span style="color: #ff00ff;">0</span>(默认不显示)<br />
· 使用操纵符 showpoint noshowpoint<br />
④ 非负数(整数和浮点数)正号设置<br />
向流中插入非负数(包括<span style="color: #ff00ff;">0</span>)时是否显示正号+ (默认不显示)<br />
· 使用操纵符 showpos noshowpos<br />
⑷ 对齐和填充格式<br />
① 使用操纵符 setw( streamsize ) 可指定下次对流的插入操作的最小字段长度<br />
注: 和endl一样，它不改变流的内部状态，只影响下一个输出<br />
② 使用操纵符 setfill( <span style="color: #2e8b57;"><strong>char</strong></span> ) 设置向流中插入对象时用来填充字段的字符(默认为空格)<br />
③ 字段内对齐方式设置(默认左对齐)<br />
· 使用操纵符left right internal<br />
关于internal:<br />
- 对数值表示左对齐前缀(正负号和十六进制的0x)右对齐数值<br />
- 对非数值则与 right 等效<br />
⑸ 空白字符的处理<br />
· 使用操纵符 skipws noskipws 设置从流中提取对象时是否忽略空白字符(默认忽略)<br />
· 使用操纵符 ws 忽略输入序列中从当前位置开始尽可能多的空白字符，直到遇到非空白字符才停止<br />
当然，如果已经(默认)设置了 skipws 则没有必要使用 ws</p>
<p>⒏ 无格式I/O操作<br />
⑴ 单字节操作<br />
① istream&amp; get ( <span style="color: #2e8b57;"><strong>char</strong></span>&amp; );<br />
istream 的公共成员函数，从流中提取一个字符存入实参中<br />
<span style="color: #2e8b57;"><strong>int</strong></span> get( );<br />
无参数版本从流中提取一个字符并返回其值<br />
② ostream&amp; put ( <span style="color: #2e8b57;"><strong>char</strong></span> );<br />
ostream 的公共成员函数，将字符参数值写入输出缓冲区并返回*<span style="color: #804040;"><strong>this</strong></span><br />
③ istream&amp; putback ( <span style="color: #2e8b57;"><strong>char</strong></span> );<br />
istream 的公共成员函数，将字符参数值放回流中并返回*<span style="color: #804040;"><strong>this</strong></span><br />
④ istream&amp; unget ( );<br />
istream 的公共成员函数，将流退回<span style="color: #ff00ff;">1</span>字节并返回*<span style="color: #804040;"><strong>this</strong></span><br />
⑤ <span style="color: #2e8b57;"><strong>int</strong></span> peek ( );<br />
istream 的公共成员函数，读取并返回流中的下一个字符，但不提取它<br />
注: 为允许返回EOF，put(无参数版本)和peek的返回值都为 <span style="color: #2e8b57;"><strong>int</strong></span><br />
⑵ 多字节操作<br />
① istream&amp; get (<span style="color: #2e8b57;"><strong>char</strong></span>* s, streamsize n, <span style="color: #2e8b57;"><strong>char</strong></span> delim );<br />
istream 的公共成员函数，不断从流中提取字符并以字符串形式存入s指向首地址的数组，<br />
直到出现以下情况之一:<br />
- 已经提取了(n-<span style="color: #ff00ff;">1</span>)个字符;<br />
- 遇到了定界字符delim(如果不提供此参数则为<span style="color: #6a5acd;">&#8216;\n&#8217;</span>);<br />
(被找到的定界字符不会被提取，而是继续留在流中作为下一个要被提取的字符)<br />
- 到达文件末尾;<br />
- 提取过程中发生错误;<br />
最后返回*<span style="color: #804040;"><strong>this</strong></span>.<br />
注: 提取的字符以字符串的形式储存，故将自动添加结尾的<span style="color: #6a5acd;">&#8216;\0&#8242;</span>，而被提取的最大字符数也为(n-<span style="color: #ff00ff;">1</span>)而非n<br />
② istream&amp; getline (<span style="color: #2e8b57;"><strong>char</strong></span>* s, streamsize n, <span style="color: #2e8b57;"><strong>char</strong></span> delim );<br />
istream 的公共成员函数，与上面参数表相同的get版本类似，唯一区别在于定界字符会被提取并丢弃<br />
③ istream&amp; read ( <span style="color: #2e8b57;"><strong>char</strong></span>* s, streamsize n );<br />
istream 的公共成员函数，从流中提取n个字符存入s指向首地址的数组，<br />
直到出现以下情况之一：<br />
- 已经提取了n个字符<br />
- 到达文件末尾(eofbit和failbit会被设置)<br />
- 提取过程中发生错误<br />
最后返回*<span style="color: #804040;"><strong>this</strong></span>.<br />
注: 与get和getline不同，read不把提取的字符保存为字符串，故不会自动加上<span style="color: #6a5acd;">&#8216;\0&#8242;</span><br />
④ streamsize  gcount ( ) <span style="color: #2e8b57;"><strong>const</strong></span>;<br />
istream 的公共成员函数，返回上次无格式输入操作提取的字符个数<br />
(peek, putback, unget不提取字符，故对此gcount返回<span style="color: #ff00ff;">0</span>)<br />
⑤ ostream&amp; write ( <span style="color: #2e8b57;"><strong>const</strong></span> <span style="color: #2e8b57;"><strong>char</strong></span>* s , streamsize n );<br />
ostream 的公共成员函数，把s指向首地址的数组的前n个字符写入输出流缓冲区<br />
⑥ istream&amp;  ignore ( streamsize n = <span style="color: #ff00ff;">1</span>, <span style="color: #2e8b57;"><strong>int</strong></span> delim = <span style="color: #ff00ff;">EOF</span> );<br />
istream 的公共成员函数，从流中提取并抛弃字符，直到:<br />
- 已经提取了n个字符或遇到了定界字符delim(该字符不会被提取)<br />
最后返回*<span style="color: #804040;"><strong>this</strong></span>.</p>
<p>⒐ 流的随机访问<br />
⑴ 用于随机访问的成员函数<br />
· pos_type tellg ();<br />
pos_type tellp ();<br />
返回输入/输出流中的标记当前的绝对位置<br />
· istream&amp; seekg ( pos_type pos );<br />
ostream&amp; seekp ( pos_type pos );<br />
将输入/输出流中的标记重新定位至参数值表示的位置<br />
· istream&amp; seekg ( off_type off, ios_base::seekdir dir );<br />
ostream&amp; seekp ( off_type off, ios_base::seekdir dir );<br />
将输入/输出流中的标记重新定位至距离dir偏移量为off的位置<br />
⑵ 关于上述函数参数和返回值的类型<br />
① pos_type和off_type都是类的成员类型，分别表示流中的标记位置和偏移量<br />
后者可正可负，分别表示向前和向后偏移<br />
② seekdir类型用来表示偏移的启示位置，其可能值如下<br />
beg 流的开头<br />
cur 流的当前位置<br />
end 流的末尾<br />
⑶ 以上tell和seek版本分别有两个版本g(get)和p(put)<br />
其区别在于g版是istream类的成员，而p版是ostream类的成员<br />
对于iostream对象，而者都适用，它们都操作同一个标记(而非输入输出各一个)<br />
⑷ 普通iostream对象一般不允许随机访问，以上内容主要适用fstream和sstream</p>

<hr/><blockquote><p>可能你对下面的文章也感兴趣：</p><ol>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter4/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第四章'>C++ Primer 读书笔记 &#8211; 第四章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter2/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第二章'>C++ Primer 读书笔记 &#8211; 第二章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter5/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第五章'>C++ Primer 读书笔记 &#8211; 第五章</a></li>
</ol></blockquote>]]></content:encoded>
			<wfw:commentRss>http://blog.tomtung.com/2008/09/cpp-primer-reding-notes-chapter8/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>C++ Primer 读书笔记 &#8211; 第七章</title>
		<link>http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter7/</link>
		<comments>http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter7/#comments</comments>
		<pubDate>Thu, 28 Aug 2008 09:14:50 +0000</pubDate>
		<dc:creator>逆铭</dc:creator>
				<category><![CDATA[新长征路上的代码]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[笔记]]></category>

		<guid isPermaLink="false">http://blog.tomtung.com/2008/08/c-primer-%e8%af%bb%e4%b9%a6%e7%ac%94%e8%ae%b0-%e7%ac%ac%e4%b8%83%e7%ab%a0/</guid>
		<description><![CDATA[<a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter7/" title="C++ Primer 读书笔记 - 第七章"></a>[笔记索引] 第７章 函数 ㈠ 函数的声明和定义 ⒈ 与变量类似： ⑴ 函数必须在调用前声明 ⑵ 函数声明可与定义分离 ⑶ 一个函数只能定义一次但可声明多次 ⒉ 函数声明由函数返回类型、函数返回类型和形参列表组成 三者描述了函数的接口，称为函数原型(function prototype) ⑴ 函数的操作数，即形参(parameter)，在一对圆括号中声明，并以逗号分隔 形参名是可选的，但形参需要在定义函数时命名才能使用 ⑵ 函数执行的运算在一个称为函数体(function body)的块语句中定义 ⒊ 函数一般在头文件中声明，在源文件中定义 此时应使后者包含前者，以便编译器检查定义和声明是否一致 ⒋ 将一个较小的、常被调用的函数指定为 inline 可使函数在调用点展开，以避免调用函数的额外开销 但内联说明对编译器来说只是一个建议，编译器也可能选择忽略 ㈡ 函数的调用和参数传递 ⒈ 函数的调用 ⑴ 使用调用操作符()实现函数调用 ① 操作数是函数名和一组(可能为空的)用逗号分开的实参(argument) ② &#8230;<p class="read-more"><a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter7/">继续阅读 &#187;</a></p><hr/><blockquote>
可能你对下面的文章也感兴趣：<ol>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter4/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第四章'>C++ Primer 读书笔记 &#8211; 第四章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter2/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第二章'>C++ Primer 读书笔记 &#8211; 第二章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter5/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第五章'>C++ Primer 读书笔记 &#8211; 第五章</a></li>
</ol></blockquote>]]></description>
			<content:encoded><![CDATA[<a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter7/" title="C++ Primer 读书笔记 - 第七章"></a><p style="text-align: right;"><a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-index/" target="_blank"><span style="font-size: 12px;"> [笔记索引]</span></a></p>
<p><span style="font-size: 12px;">第７章 函数</span></p>
<p><span style="font-size: 12px;"> ㈠ 函数的声明和定义<br />
⒈ 与变量类似：<br />
⑴ 函数必须在调用前声明<br />
⑵ 函数声明可与定义分离<br />
⑶ 一个函数只能定义一次但可声明多次<br />
⒉ 函数声明由函数返回类型、函数返回类型和形参列表组成<br />
三者描述了函数的接口，称为函数原型(function prototype)<br />
⑴ 函数的操作数，即形参(parameter)，在一对圆括号中声明，并以逗号分隔<br />
形参名是可选的，但形参需要在定义函数时命名才能使用<br />
⑵ 函数执行的运算在一个称为函数体(function body)的块语句中定义<br />
⒊ 函数一般在头文件中声明，在源文件中定义<br />
此时应使后者包含前者，以便编译器检查定义和声明是否一致<br />
⒋ 将一个较小的、常被调用的函数指定为 </span><span style="color: #2e8b57;"><strong>inline</strong></span> 可使函数在调用点展开，以避免调用函数的额外开销<br />
但内联说明对编译器来说只是一个建议，编译器也可能选择忽略</p>
<p>㈡ 函数的调用和参数传递<br />
⒈ 函数的调用<br />
⑴ 使用调用操作符()实现函数调用<br />
① 操作数是函数名和一组(可能为空的)用逗号分开的实参(argument)<br />
② 结果类型为函数返回值的类型，结果为函数的返回值<br />
⑵ 函数调用做两件事：<br />
① 首先(隐式)定义形参，并用对应的实参进行初始化<br />
· 形参的初始化与变量一样：<br />
如果形参为非引用类型则复制实参的值，如果形参为引用类型则它只是实参的别名<br />
② 主调函数(calling function)的执行被挂起，被调函数(called function)开始执行<br />
⒉ 非引用形参<br />
⑴ 指针形参<br />
① 可以通过传入指针来间接访问指针所指对象<br />
② 若需要保护指针指向的对象，可指定形参为指向 <span style="color: #2e8b57;"><strong>const</strong></span> 对象的指针<br />
⑵ <span style="color: #2e8b57;"><strong>const</strong></span> 形参<br />
① 用来初始化 <span style="color: #2e8b57;"><strong>const</strong></span> 形参的实参无论是不是 <span style="color: #2e8b57;"><strong>const</strong></span> 都可以<br />
在函数中不能改变该实参的局部副本<br />
② 非引用形参是否为 <span style="color: #2e8b57;"><strong>const</strong></span> 不影响编译器对其所属函数类型的判别<br />
·注：对于指针，注意区分 <span style="color: #2e8b57;"><strong>const</strong></span> 是修饰指针本身的性质还是所指对象的性质<br />
⑶ 不适合复制实参的情况<br />
① 需要修改实参值时<br />
② 需要将大型对象作为实参传递时<br />
③ 无法复制对象时<br />
以上情况可通过将形参定义为指针或引用类型解决<br />
⒊ 引用形参<br />
⑴ 可以使用引用形参返回额外信息<br />
⑵ 可以利用 <span style="color: #2e8b57;"><strong>const</strong></span> 引用形参避免复制实参<br />
⑶ 使用引用形参时，将不需要修改的定义为 <span style="color: #2e8b57;"><strong>const</strong></span> 会更灵活<br />
非 <span style="color: #2e8b57;"><strong>const</strong></span> 引用形参不能用 <span style="color: #2e8b57;"><strong>const</strong></span> 左值或右值初始化，而定义为 <span style="color: #2e8b57;"><strong>const</strong></span> 则无此问题<br />
⒋ 一般通过传递迭代器来传递 vector 等容器<br />
⒌ 数组形参<br />
⑴ 当把数组直接作为实参传给函数时：<br />
① 若形参不是数组的引用，则自动转换为指向首元素的指针<br />
例如以下三种定义完全等价：<br />
<span style="color: #2e8b57;"><strong>void</strong></span> f(<span style="color: #2e8b57;"><strong>int</strong></span>*); <span style="color: #0000ff;">//推荐，明确指出操作对象为指针</span><br />
<span style="color: #2e8b57;"><strong>void</strong></span> f(<span style="color: #2e8b57;"><strong>int</strong></span>[]);<br />
<span style="color: #2e8b57;"><strong>void</strong></span> f(<span style="color: #2e8b57;"><strong>int</strong></span>[<span style="color: #ff00ff;">10</span>]);<span style="color: #0000ff;">//维数被编译器忽略，写法容易引起误解</span><br />
② 若形参是数组的引用则不发生转换，函数得到的是数组本身<br />
此时编译器会检查形参和实参数组的维数是否匹配<br />
⑵ 把数组传递给函数处理时，可以：<br />
⒈ 使用标准库规范，即传入首元素指针和超出末端指针<br />
⒉ 传递数组首元素地址，并显式传递表示数组大小的形参<br />
⑶ 可以通过传递指向数组的指针来传递多维数组<br />
⒍ 含有可变形参的函数<br />
为兼容C语言而保留的特性，只能传入简单数据类型，大多数类类型对象都不能正确复制<br />
⒎ 默认实参<br />
⑴ 通过给形参表中的形参提供明确的初值可指定默认实参，如<br />
<span style="color: #2e8b57;"><strong>void</strong></span> f( <span style="color: #2e8b57;"><strong>int</strong></span>, <span style="color: #2e8b57;"><strong>int</strong></span> = <span style="color: #ff00ff;">1</span>, <span style="color: #2e8b57;"><strong>int</strong></span> = <span style="color: #ff00ff;">2</span> );<br />
① 默认实参可以是任何适当类型的表达式<br />
② 如果一个形参有默认实参，则其后的所有形参都必须有默认实参<br />
③ 在一个文件中，只能为一个形参指定默认实参一次<br />
通常应在函数声明中指定默认实参，并将该声明放在合适的头文件中<br />
⑵ 调用函数时可省略有默认值的实参：若省略则使用默认实参，否则使用用户提供的实参<br />
· 默认实参只能用来替换函数调用缺少的靠后的实参<br />
因此设计带有默认实参的函数时，应将最少使用默认实参的形参排在最前，最多使用默认实参的形参排在最后</p>
<p>㈢ 局部对象的作用域和生命期<br />
⒈ 函数体是一个作用域，在其中定义的变量称为局部变量(local variable)，只可在该函数中访问<br />
局部变量和形参均不能重名<br />
⒉ 自动对象(automatic objects)是局部于函数的对象，会在每次函数调用时重新创建，并在函数结束时撤销<br />
非静态局部变量和形参都是自动对象<br />
⒊ <span style="color: #2e8b57;"><strong>static</strong></span> 局部对象确保不迟于在程序执行流程第一次经过该对象的定义语句时初始化，一旦创建在程序结束前都不会撤销<br />
在所在函数被多次调用的过程中，static 局部对象会持续存在并保持它的值</p>
<p>㈣ 函数的返回值和 <span style="color: #804040;"><strong>return</strong></span> 语句<br />
⒈ 函数返回类型可为内置类型、类类型或复合类型，但不能是另一个函数或内置数组类型<br />
为 <span style="color: #2e8b57;"><strong>void</strong></span> 类型表示该函数不返回任何值<br />
⒉ <span style="color: #804040;"><strong>return</strong></span> 语句<br />
用于结束当前函数，将控制权返回给该函数的主调函数<br />
⑴ 没有返回值的 <span style="color: #804040;"><strong>return</strong></span> 语句<br />
① 只能用于返回类型为 <span style="color: #2e8b57;"><strong>void</strong></span> 的函数<br />
② 非必需，隐式 <span style="color: #804040;"><strong>return</strong></span> 发生在函数最后一个语句完成时<br />
⑵ 具有返回值的 <span style="color: #804040;"><strong>return</strong></span> 语句<br />
① 返回类型不是 <span style="color: #2e8b57;"><strong>void</strong></span> 的函数必须返回一个值(主函数 main 除外)<br />
注：应在函数中的每条执行路径末尾都提供 <span style="color: #804040;"><strong>return</strong></span> 语句；若不提供编译器可能也无法发现<br />
② 用函数返回值初始化在调用函数处创建的临时对象，与用实参初始化形参的方法一样<br />
即若返回非引用类型则得到副本，若返回引用类型则得到对象本身<br />
③ 切勿返回局部对象的引用或指针</p>
<p>㈤ 函数的重载<br />
⒈ 出现在相同作用域中的两个函数，如果具有相同的名字而形参表不同，则为重载函数(overloaded function)<br />
仅仅是返回类型不同、默认实参不同、非引用形参的 <span style="color: #2e8b57;"><strong>const</strong></span> 性质不同不能实现重载<br />
⒉ 若局部地声明函数，则该函数屏蔽而非重载在外层作用域中声明的同名函数<br />
⒊ 重载确定的三个步骤<br />
⑴ 确定候选函数集合<br />
候选函数(candidate function)是与被调函数同名的函数，且在调用点上声明可见<br />
⑵ 从候选函数集合中选择可行函数(找不到则此调用错误)<br />
可行函数(viable function)满足两个条件：<br />
① 函数形参与该调用的实参个数匹配(考虑默认实参)<br />
② 每个实参的类型须与对应形参匹配(类型相同或可隐式转换)<br />
⑶ 寻找最佳匹配(有多个匹配程度相同的则调用有二义性)<br />
原则是实参类型与形参类型越接近则匹配越佳。具体匹配程度从高到低为：<br />
① 精确匹配：实参与形参类型相同<br />
② 通过类型提升实现的匹配<br />
③ 通过标准转换实现的匹配<br />
④ 通过类类型转换实现的匹配</p>
<p>㈥ 函数指针<br />
⒈ 定义形式<br />
返回类型 (*标识符)(形参表)<br />
⒉ 可使用 <span style="color: #2e8b57;"><strong>typedef</strong></span> 简化定义<br />
<span style="color: #2e8b57;"><strong>typedef</strong></span> 返回类型 (*自定义类型名)(形参表)<br />
⒊ 对函数指针进行初始化和赋值，可使用：<br />
⑴ 同类型的函数<br />
引用函数名但不调用该函数时，函数名被自动解释为指向函数的指针<br />
因此可以直接使用函数名对函数指针初始化或赋值，不需要使用取地址操作符&amp;<br />
·注：指针类型须与函数完全匹配<br />
⑵ 同类型的函数指针<br />
⑶ <span style="color: #ff00ff;">0</span>值常量表达式<br />
⒋ 通过函数指针调用函数<br />
可以不使用解引用操作符，直接使用函数调用操作符()调用所指函数<br />
⒌ 函数指针作形参时，星号*可写可不写<br />
⒍ 函数的指针作函数返回值<br />
函数指针返回类型 (*函数名(函数形参表))(函数指针形参表)</p>
<p>㈦ 主函数 main<br />
⒈ 返回值<br />
⑴ 主函数返回类型为 <span style="color: #2e8b57;"><strong>int</strong></span>, 返回值在大多数系统中是一个状态指示器<br />
返回<span style="color: #ff00ff;">0</span>表示程序运行成功，其它大部分值表示失败<br />
⑵ 不需要显式使用 <span style="color: #804040;"><strong>return</strong></span> 语句，编译器将隐式插入返回<span style="color: #ff00ff;">0</span>的语句<br />
⑶ 为使返回值独立于机器，cstdlib 头文件定义了两个预处理变量<br />
<span style="color: #ff00ff;">EXIT_FAILURE</span>(运行失败)    <span style="color: #ff00ff;">EXIT_SUCCESS</span>(运行成功)<br />
⒉ 使用主函数形参处理命令行选项<br />
<span style="color: #2e8b57;"><strong>int</strong></span> main(<span style="color: #2e8b57;"><strong>int</strong></span> argc, <span style="color: #2e8b57;"><strong>char</strong></span>* argv[])<br />
· argv为一个C风格字符串数组，储存了从命令行调用程序时输入的字符串(包括程序名和参数)<br />
· argc表示argv中字符串的个数<br />
⒊ 主函数 main 不允许被显式调用、取地址或重载</p>

<hr/><blockquote><p>可能你对下面的文章也感兴趣：</p><ol>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter4/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第四章'>C++ Primer 读书笔记 &#8211; 第四章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter2/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第二章'>C++ Primer 读书笔记 &#8211; 第二章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter5/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第五章'>C++ Primer 读书笔记 &#8211; 第五章</a></li>
</ol></blockquote>]]></content:encoded>
			<wfw:commentRss>http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter7/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>C++ Primer 读书笔记 &#8211; 第六章</title>
		<link>http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter6/</link>
		<comments>http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter6/#comments</comments>
		<pubDate>Sun, 24 Aug 2008 09:01:47 +0000</pubDate>
		<dc:creator>逆铭</dc:creator>
				<category><![CDATA[新长征路上的代码]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[笔记]]></category>

		<guid isPermaLink="false">http://blog.tomtung.com/2008/08/c-primer-%e8%af%bb%e4%b9%a6%e7%ac%94%e8%ae%b0-%e7%ac%ac%e5%85%ad%e7%ab%a0/</guid>
		<description><![CDATA[<a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter6/" title="C++ Primer 读书笔记 - 第六章"></a>[笔记索引] 第６章 语句 ㈠ 简单语句 ⒈ 表达式语句(expression_r statement) 一个表达式加上结尾的分号，执行时导致该表达式被求值 ⒉ 空语句(null statement) 只由一个单独的分号组成，当语法上需要一个语句但逻辑上并不需要时使用 ⒊ 声明语句 用于声明或定义对象或类 ㈡ 复合语句 ⒈ 复合语句(compound statement)又被称为块(block)，是用一对花括号{}括起的(可能为空的)语句序列 ⒉ 通常用于语法规则要求使用单个语句但程序逻辑需要多个语句时 ⒊ 块标示了一个作用域，在块中引入的名字只能在其内部访问 ㈢ 控制流语句 注：作为语句控制结构的一部分定义的变量，仅在该语句内可见 ⒈ 条件分支结构 ⑴ if 语句 关于 else-if 匹配的二义性问题: else 匹配给最后出现尚未匹配的 if ⑵ &#8230;<p class="read-more"><a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter6/">继续阅读 &#187;</a></p><hr/><blockquote>
可能你对下面的文章也感兴趣：<ol>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter5/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第五章'>C++ Primer 读书笔记 &#8211; 第五章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter4/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第四章'>C++ Primer 读书笔记 &#8211; 第四章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter3/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第三章'>C++ Primer 读书笔记 &#8211; 第三章</a></li>
</ol></blockquote>]]></description>
			<content:encoded><![CDATA[<a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter6/" title="C++ Primer 读书笔记 - 第六章"></a><p style="text-align: right;"><a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-index/" target="_blank"><span style="font-size: 12px;"> [笔记索引]</span></a></p>
<p><span style="font-size: 12px;">第６章 语句<br />
㈠ 简单语句<br />
⒈ 表达式语句(expression_r statement)<br />
一个表达式加上结尾的分号，执行时导致该表达式被求值<br />
⒉ 空语句(null statement)<br />
只由一个单独的分号组成，当语法上需要一个语句但逻辑上并不需要时使用<br />
⒊ 声明语句<br />
用于声明或定义对象或类<br />
㈡ 复合语句<br />
⒈ 复合语句(compound statement)又被称为块(block)，是用一对花括号{}括起的(可能为空的)语句序列<br />
⒉ 通常用于语法规则要求使用单个语句但程序逻辑需要多个语句时<br />
⒊ 块标示了一个作用域，在块中引入的名字只能在其内部访问<br />
㈢ 控制流语句<br />
注：作为语句控制结构的一部分定义的变量，仅在该语句内可见<br />
⒈ 条件分支结构<br />
⑴ </span><span style="color: #804040;"><strong>if</strong></span> 语句<br />
关于 <span style="color: #804040;"><strong>else</strong></span>-<span style="color: #804040;"><strong>if</strong></span> 匹配的二义性问题: <span style="color: #804040;"><strong>else</strong></span> 匹配给最后出现尚未匹配的 <span style="color: #804040;"><strong>if</strong></span><br />
⑵ <span style="color: #804040;"><strong>switch</strong></span> 语句<br />
① <span style="color: #804040;"><strong>switch</strong></span> 在计算表达式的值后跳转到匹配的标号处(无匹配则跳转至 <span style="color: #804040;"><strong>default</strong></span>)，并从该点开始一直执行下去，<br />
直至 <span style="color: #804040;"><strong>switch</strong></span> 语句结束或遇到 <span style="color: #804040;"><strong>break</strong></span> 语句<br />
② <span style="color: #804040;"><strong>switch</strong></span> 求解表达式的结果须为整型，每个 <span style="color: #804040;"><strong>case</strong></span> 标号的值也须为各不相同的整型常量表达式<br />
③ <span style="color: #804040;"><strong>switch</strong></span> 内部的变量定义<br />
· 可以在 <span style="color: #804040;"><strong>switch</strong></span> 求解的表达式中定义和初始化变量<br />
· 为防止跳过变量定义，只允许在最后一个标号后定义变量<br />
· 也可以引入块语句，在其中定义变量<br />
⒉ 循环<br />
⑴ <span style="color: #804040;"><strong>while</strong></span> 语句<br />
注：循环条件中定义的变量在每次循环时都要经历创建和撤销的过程<br />
⑵ <span style="color: #804040;"><strong>for</strong></span> 循环语句<br />
注：语句头中的初始化语句、循环条件和表达式三者都可以省略<br />
循环条件省略表示永远为 <span style="color: #ff00ff;">true</span><br />
⑶ <span style="color: #804040;"><strong>do</strong></span> <span style="color: #804040;"><strong>while</strong></span> 语句<br />
注：不能在循环条件中定义变量<br />
⒊ <span style="color: #804040;"><strong>break</strong></span> 语句<br />
用于结束最近的外围 <span style="color: #804040;"><strong>while</strong></span>, <span style="color: #804040;"><strong>do</strong></span> <span style="color: #804040;"><strong>while</strong></span>, <span style="color: #804040;"><strong>for</strong></span> 或 <span style="color: #804040;"><strong>switch</strong></span> 语句，并在该语句后继续执行<br />
⒋ <span style="color: #804040;"><strong>continue</strong></span> 语句<br />
导致最近的外围循环语句(<span style="color: #804040;"><strong>for</strong></span>, <span style="color: #804040;"><strong>while</strong></span>, <span style="color: #804040;"><strong>do</strong></span> <span style="color: #804040;"><strong>while</strong></span>)正在进行的这次迭代提前结束<br />
⒌ <span style="color: #804040;"><strong>goto</strong></span> 语句<br />
⑴ <span style="color: #804040;"><strong>goto</strong></span> 语句提供了函数内部的无条件跳转，实现从 <span style="color: #804040;"><strong>goto</strong></span> 语句跳转到同一函数内某个带标号的语句<br />
除非有足够理由，应避免使用 <span style="color: #804040;"><strong>goto</strong></span> 语句<br />
⑵ 在任何语句前提供一个标识符和冒号，就得到一个带标号的语句(labeled statement)<br />
标识符: 语句<br />
使用 <span style="color: #804040;"><strong>goto</strong></span> 语句跳转到该语句： <span style="color: #804040;"><strong>goto</strong></span> 标识符;<br />
由于这里的标识符只能用作 <span style="color: #804040;"><strong>goto</strong></span> 的目标，因此可以与其它类型的标识符(如变量名)同名<br />
⑶ <span style="color: #804040;"><strong>goto</strong></span> 语句不能跨越变量的定义语句向前跳转<br />
若确实需在 <span style="color: #804040;"><strong>goto</strong></span> 和跳转目标位置间定义变量，则须定义在块中<br />
⒍ <span style="color: #804040;"><strong>try</strong></span>, <span style="color: #804040;"><strong>catch</strong></span> 语句和 <span style="color: #804040;"><strong>throw</strong></span> 表达式<br />
用于异常处理<br />
⒎ <span style="color: #804040;"><strong>return</strong></span> 语句<br />
用于结束当前函数，返回函数被调用处继续执行</p>
<p>⒍⒕ 使用预处理器进行调试<br />
⒈ 使用 NDEBUG 预处理变量实现有条件的调试代码(类似头文件保护符)<br />
<span style="color: #a020f0;"> #ifndef NDEBUG</span><br />
<span style="color: #a020f0;"> #define NDEBUG</span><br />
<span style="color: #0000ff;">// 调试代码</span><br />
<span style="color: #a020f0;"> #endif</span><br />
如果定义了 NDEBUG 就不执行调试代码<br />
⒉ 使用 NDEBUG 预处理变量以及 assert 预处理宏<br />
定义在头文件cassert中，常用来检查不可能发生的状况，形式为<br />
assert(表达式)<br />
如果表达式结果为 <span style="color: #ff00ff;">false</span>, assert 输出信息并终止程序<br />
如果定义了 NDEBUG 预处理变量，assert 将被忽略，不会产生任何运行时代价<br />
⒊ 预处理器定义了四种在调试时有用的常量<br />
<span style="color: #ff00ff;">__FILE__</span> 文件名<br />
<span style="color: #ff00ff;">__LINE__</span> 当前行号<br />
<span style="color: #ff00ff;">__TIME__</span> 编译时间<br />
<span style="color: #ff00ff;">__DATE__</span> 编译日期</p>

<hr/><blockquote><p>可能你对下面的文章也感兴趣：</p><ol>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter5/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第五章'>C++ Primer 读书笔记 &#8211; 第五章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter4/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第四章'>C++ Primer 读书笔记 &#8211; 第四章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter3/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第三章'>C++ Primer 读书笔记 &#8211; 第三章</a></li>
</ol></blockquote>]]></content:encoded>
			<wfw:commentRss>http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter6/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>C++ Primer 读书笔记 &#8211; 第五章</title>
		<link>http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter5/</link>
		<comments>http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter5/#comments</comments>
		<pubDate>Fri, 22 Aug 2008 17:31:47 +0000</pubDate>
		<dc:creator>逆铭</dc:creator>
				<category><![CDATA[新长征路上的代码]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[笔记]]></category>

		<guid isPermaLink="false">http://blog.tomtung.com/2008/08/c-primer-%e8%af%bb%e4%b9%a6%e7%ac%94%e8%ae%b0-%e7%ac%ac%e4%ba%94%e7%ab%a0/</guid>
		<description><![CDATA[<a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter5/" title="C++ Primer 读书笔记 - 第五章"></a>[笔记索引] 第５章 表达式 ⒈ 表达式(expression_r)是一个C++程序中最低级的计算，由一或多个用一个操作符(operator)连接起来的操作数(operands)组成 ⒉ 每个表达式都产生一个结果。表达式可以用作操作数，因此可用多个操作符编写复合表达式 ⒊ 在求解表达式的过程中如果需要储存运算结果，编译器会自动创建没有名字的临时对象(temporary object)，这些对象会在外围最大的表达式结束后释放 ⒋ 表达式是否合法、合法表达式含义如何(执行什么操作、结果是什么类型)均取决于操作数的类型 ⒌⒈ 算术操作符 ⒈ 按优先级从高到低排列为： 一元正+, 一元负-; 乘法*, 除法/, 取模%; 加法+, 减法- ⒉ 关于除法/ ⑴ 两整数相除结果仍为整数，商的小数部分被截去 ⑵ 一正一负两整数相除，结果值向0一侧还是向-∞一侧取整依赖于机器 ⒊ 关于取模 ⑴ 操作数只能为整型 ⑵ 两操作数均为负时结果为负或0; 两操作数一正一负时，结果的符号随哪个操作数而定依赖于机器 ⒌⒉ 关系操作符和逻辑操作符 ⒈ 按优先级从高到低排列为： &#8230;<p class="read-more"><a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter5/">继续阅读 &#187;</a></p><hr/><blockquote>
可能你对下面的文章也感兴趣：<ol>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter2/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第二章'>C++ Primer 读书笔记 &#8211; 第二章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter4/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第四章'>C++ Primer 读书笔记 &#8211; 第四章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter3/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第三章'>C++ Primer 读书笔记 &#8211; 第三章</a></li>
</ol></blockquote>]]></description>
			<content:encoded><![CDATA[<a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter5/" title="C++ Primer 读书笔记 - 第五章"></a><p style="text-align: right;"><a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-index/" target="_blank"><span style="font-size: 12px;"> [笔记索引]</span></a></p>
<p><span style="font-size: 12px;">第５章 表达式<br />
⒈ 表达式(expression_r)是一个C++程序中最低级的计算，由一或多个用一个操作符(operator)连接起来的操作数(operands)组成<br />
⒉ 每个表达式都产生一个结果。表达式可以用作操作数，因此可用多个操作符编写复合表达式<br />
⒊ 在求解表达式的过程中如果需要储存运算结果，编译器会自动创建没有名字的临时对象(temporary object)，这些对象会在外围最大的表达式结束后释放<br />
⒋ 表达式是否合法、合法表达式含义如何(执行什么操作、结果是什么类型)均取决于操作数的类型</span></p>
<p><span style="font-size: 12px;"> ⒌⒈ 算术操作符<br />
⒈ 按优先级从高到低排列为：<br />
一元正+, 一元负-; 乘法*, 除法/, 取模%; 加法+, 减法-<br />
⒉ 关于除法/<br />
⑴ 两整数相除结果仍为整数，商的小数部分被截去<br />
⑵ 一正一负两整数相除，结果值向</span><span style="color: #ff00ff;">0</span>一侧还是向-∞一侧取整依赖于机器<br />
⒊ 关于取模<br />
⑴ 操作数只能为整型<br />
⑵ 两操作数均为负时结果为负或<span style="color: #ff00ff;">0</span>;<br />
两操作数一正一负时，结果的符号随哪个操作数而定依赖于机器</p>
<p>⒌⒉ 关系操作符和逻辑操作符<br />
⒈ 按优先级从高到低排列为：<br />
逻辑非!; 小于&lt;, 小于等于&lt;=, 大于&gt;, 大于等于&gt;=; 相等==, 不等!=; 逻辑与&amp;&amp;; 逻辑或||<br />
⒉ 关系操作符和逻辑操作符接受算术或指针型操作数，并返回 <span style="color: #2e8b57;"><strong>bool</strong></span> 型值<br />
逻辑操作符视其操作数为条件表达式<br />
⒊ 逻辑与&amp;&amp;和逻辑或||操作符支持短路求值(short-circuit evaluation)<br />
⒋ 不应串接使用关系操作符<br />
形如i&lt;j&lt;k的表达式得不到预期结果</p>
<p>⒌⒊ 位操作符<br />
⒈ 按优先级从高到低排列为：<br />
位取反~; 左移&lt;&lt;, 右移&gt;&gt;; 位与&amp;; 位异或^; 位或|<br />
⒉ 位操作符使用整型操作数，将其视为二进制位的集合<br />
由于负整数的符号位如何处理依赖于机器，因此应使用 <span style="color: #2e8b57;"><strong>unsigned</strong></span> 整型操作数</p>
<p>⒌⒋ 赋值操作符<br />
⒈ 赋值操作符的左操作数须为非 <span style="color: #2e8b57;"><strong>const</strong></span> 左值<br />
赋值表达式的结果即为其左操作数(左值)<br />
⒉ 赋值操作符从右向左结合，因此当各操作数都有相同的通用类型时，允许在一个表达式中进行多次赋值，如：<br />
i = j = k = <span style="color: #ff00ff;">0</span>;<br />
⒊ 复合赋值操作符<br />
对于任意二元算术操作符或二元位操作符 op<br />
a op= b;<br />
相当于<br />
a = a op b;<br />
二者显著的差别在于前者只计算了一次左操作数，后者则计算了两次</p>
<p>⒌⒌ 自增和自减操作符<br />
⒈ 自增++和自减&#8211;操作符为对象加<span style="color: #ff00ff;">1</span>或减<span style="color: #ff00ff;">1</span>提供了方便简短的实现方式，有前置和后置两种使用形式<br />
前置操作返回加(减)<span style="color: #ff00ff;">1</span>后的对象(左值)，后置操作返回操作数的原值(右值)<br />
⒉ 出于性能考虑，应只在必要时才使用后置操作符<br />
后置操作符需要先保存原值以便返回，而前置操作符只需加(减)<span style="color: #ff00ff;">1</span>后直接返回对象即可</p>
<p>⒌⒍ 箭头操作符<br />
箭头操作符用于获取指针指向类类型对象的成员。<br />
下面两个表达式等价：<br />
p-&gt;foo;<br />
(*p).foo;</p>
<p>⒌⒎ 条件操作符<br />
⒈ 条件操作符是C++中唯一的三元操作符，能将简短的 <span style="color: #804040;"><strong>if</strong></span>-<span style="color: #804040;"><strong>else</strong></span> 语句嵌入表达式<br />
格式为 cond ? expr1 : expr2<br />
首先计算 cond 值，若为 <span style="color: #ff00ff;">true</span> 则计算并返回 expr1, 为 <span style="color: #ff00ff;">false</span> 则计算并返回 expr2<br />
⒉ 避免深度嵌套以保证可读性</p>
<p>⒌⒏ <span style="color: #804040;"><strong>sizeof</strong></span> 操作符<br />
⒈ <span style="color: #804040;"><strong>sizeof</strong></span> 操作符用于返回一个对象或类型的大小(单位字节，类型 <span style="color: #2e8b57;"><strong>size_t</strong></span>)<br />
形式为 <span style="color: #804040;"><strong>sizeof</strong></span> expr<br />
或  <span style="color: #804040;"><strong>sizeof</strong></span>(type_name)<br />
⒉ <span style="color: #804040;"><strong>sizeof</strong></span> 表达式的结果是编译时常量<br />
对表达式使用 <span style="color: #804040;"><strong>sizeof</strong></span> 时该表达式的值并不会被计算<br />
⒊ 对数组作 <span style="color: #804040;"><strong>sizeof</strong></span> 将得到整个数组在内存中的长度</p>
<p>⒌⒐ 逗号操作符<br />
逗号表达式是一组由逗号分隔的表达式，从左向右计算并返回最右边表达式的值(若该表达式为左值则返回左值)</p>
<p>⒌⒒ <span style="color: #804040;"><strong>new</strong></span> 和 <span style="color: #804040;"><strong>delete</strong></span> 表达式<br />
⒈ <span style="color: #804040;"><strong>new</strong></span> 和 <span style="color: #804040;"><strong>delete</strong></span> 表达式分别用于动态创建和释放单个对象或一个数组<br />
⒉ <span style="color: #804040;"><strong>new</strong></span> 表达式<br />
⑴ <span style="color: #804040;"><strong>new</strong></span> 表达式动态创建单个对象或一个数组，并返回指向该对象或数组首元素的指针<br />
① 动态数组维数为<span style="color: #ff00ff;">0</span>值时也将返回有效的非零指针，但不能解引用<br />
② 可以创建动态的 <span style="color: #2e8b57;"><strong>const</strong></span> 对象或数组，它们无法修改但可以释放<br />
③ 如果无法获取需要的空间，系统将抛出 bad_alloc 异常<br />
⑵ 分配与对象(或数组元素)初始化<br />
① 默认内置类型不初始化，类类型调用默认构造函数(必须提供)<br />
单个对象: <span style="color: #804040;"><strong>new</strong></span> [<span style="color: #2e8b57;"><strong>const</strong></span>] 类型名<br />
一个数组: <span style="color: #804040;"><strong>new</strong></span> [<span style="color: #2e8b57;"><strong>const</strong></span>] 类型名[维数]<br />
② 添加空括号()可执行值初始化(value initialization)<br />
即内置类型对象置为<span style="color: #ff00ff;">0</span>，类类型对象调用默认构造函数(必须提供)<br />
单个对象: <span style="color: #804040;"><strong>new</strong></span> [<span style="color: #2e8b57;"><strong>const</strong></span>] 类型名()<br />
一个数组: <span style="color: #804040;"><strong>new</strong></span> [<span style="color: #2e8b57;"><strong>const</strong></span>] 类型名[维数]()<br />
注：对于后者，我使用的编译器中，VC初始化后会把元素置为<span style="color: #ff00ff;">0</span>，但mingw不会<br />
③ 执行直接初始化<br />
单个对象: <span style="color: #804040;"><strong>new</strong></span> [<span style="color: #2e8b57;"><strong>const</strong></span>] 类型名(初始化式)<br />
动态数组元素不支持类似初始化方式<br />
⒊ <span style="color: #804040;"><strong>delete</strong></span> 表达式<br />
⑴ 由 <span style="color: #804040;"><strong>new</strong></span> 动态分配的对象或数组需要显式地使用 <span style="color: #804040;"><strong>delete</strong></span> 表达式释放(否则会造成内存泄漏)<br />
⑵ <span style="color: #804040;"><strong>delete</strong></span> ptr 和 <span style="color: #804040;"><strong>delete</strong></span>[] ptr 分别释放单个对象和动态数组<br />
① 如果指针不指向由 <span style="color: #804040;"><strong>new</strong></span> 分配的对象，则对其 <span style="color: #804040;"><strong>delete</strong></span> 不合法<br />
例外：对零指针 <span style="color: #804040;"><strong>delete</strong></span> 是合法的<br />
② 读写已释放的对象或对同一内存空间多次 <span style="color: #804040;"><strong>delete</strong></span> 都可能导致错误<br />
因此 <span style="color: #804040;"><strong>delete</strong></span> 之后应立即重置该指针的值(一般重置为<span style="color: #ff00ff;">0</span>)<br />
③ 释放动态数组如果丢掉方括号[]，将可能导致编译器无法发现的错误</p>
<p>⒌⒑ 复合表达式的求值<br />
⒈ 含有两个或以上操作符的表达式称为复合表达式(compound expression_r)<br />
操作数和操作符的结合方式决定了符合表达式的值，而前者取决于操作符的优先级和结合性：<br />
操作数优先与优先级更高的操作符结合；操作符优先级相同时则由结合性决定结合方向<br />
⒉ 圆括号()凌驾于优先级之上<br />
若不确定结合方式，则使用圆括号()强制确定操作数的组合<br />
⒊ 结合方式确定并不意味着操作数的计算顺序并不确定<br />
若修改了操作数的值，则不要在同一语句的其它地方再使用它，除非操作数的计算次序不成问题<br />
⒋ <a href="http://tomtung.jimdo.com/download/141592104/48aefa26/7eef8a1fec7302d00f283d68ed6b141c80302a10/Operator+Precedence+Table.html" target="_blank"><span style="font-size: 12px;">运算符优先级与结合性表</span></a></p>
<p><span style="font-size: 12px;">⒌⒓ 类型转换<br />
⒈ 隐式类型转换<br />
两个类型间存在可转换关系，则称两个类型相关<br />
⑴ 何时发生<br />
当编译器期望获得某种类型的数据却得到另一种类型的，就会尝试自动转换类型<br />
具体情况包括：<br />
① 表达式中不同类型的多个操作数被转换到同一类型<br />
② 用作条件的表达式被转换为 </span><span style="color: #2e8b57;"><strong>bool</strong></span> 型<br />
③ 用一表达式对某变量初始化或赋值时，前者转换为后者的类型<br />
④ 给函数传递实参和返回值时可能发生隐式类型转换<br />
⑵ 内置类型转换规则<br />
① 算术类型间的转换<br />
ⅰ 浮点型转换为整型时小数部分被抛弃(在赋值、初始化等情况下发生)<br />
ⅱ 二元(算术、关系等)操作符表达式中，为试图保留精度会把较小的类型转换为较大的类型<br />
ａ类型提升<br />
· 将比 <span style="color: #2e8b57;"><strong>int</strong></span> 小的整型提升为 <span style="color: #2e8b57;"><strong>int</strong></span> 或(当 <span style="color: #2e8b57;"><strong>int</strong></span> 不足以容纳原类型的所有可能值时)<span style="color: #2e8b57;"><strong>unsigned</strong></span> <span style="color: #2e8b57;"><strong>int</strong></span><br />
· 将 <span style="color: #2e8b57;"><strong>float</strong></span> 提升为 <span style="color: #2e8b57;"><strong>double</strong></span><br />
ｂ <span style="color: #2e8b57;"><strong>signed</strong></span> 与 <span style="color: #2e8b57;"><strong>unsigned</strong></span> 之间的转换<br />
· 对于 <span style="color: #2e8b57;"><strong>signed</strong></span> 较小类型和 <span style="color: #2e8b57;"><strong>unsigned</strong></span> 较大或相同类型，前者转换为后者<br />
· 对于 <span style="color: #2e8b57;"><strong>signed</strong></span> 较大类型和 <span style="color: #2e8b57;"><strong>unsigned</strong></span> 较小类型，如何操作依赖于机器:<br />
前者若能表示后者所有可能值则后者转换为前者，否则都转换为前者的 <span style="color: #2e8b57;"><strong>unsigned</strong></span> 形式<br />
以上两种情况，负值有可能会被转换为 <span style="color: #2e8b57;"><strong>unsigned</strong></span> 导致溢出，造成意料之外的结果<br />
② 转换为指针<br />
ⅰ 表达式中的数组名会自动转换为指向数组首元素的指针<br />
但以下情况除外：<br />
ａ数组作为取地址操作符&amp;的操作数<br />
ｂ数组作为 <span style="color: #804040;"><strong>sizeof</strong></span> 操作符的操作数<br />
ｃ使用数组对数组的引用初始化时<br />
ⅱ 指向任意类型对象的指针都可转换为 <span style="color: #2e8b57;"><strong>void</strong></span>* 型<br />
ⅲ 整型常量<span style="color: #ff00ff;">0</span>可转换为任意指针类型<br />
③ <span style="color: #2e8b57;"><strong>bool</strong></span> 类型转换<br />
ⅰ 算术值和指针值转换为 <span style="color: #2e8b57;"><strong>bool</strong></span> 型<br />
<span style="color: #ff00ff;">0</span> → <span style="color: #ff00ff;">false</span> 非<span style="color: #ff00ff;">0</span> → <span style="color: #ff00ff;">true</span><br />
ⅱ <span style="color: #2e8b57;"><strong>bool</strong></span> 值转换为算术类型<br />
<span style="color: #ff00ff;">true</span> → <span style="color: #ff00ff;">1</span> <span style="color: #ff00ff;">false</span> → <span style="color: #ff00ff;">0</span><br />
④ 枚举成员转换为整型<br />
枚举类型对象或枚举成员可自动转换为整型(具体类型依赖于机器和枚举成员最大值，但至少为int)<br />
⑤ 转换为 <span style="color: #2e8b57;"><strong>const</strong></span> 对象<br />
非 <span style="color: #2e8b57;"><strong>const</strong></span> 对象在初始化相关的 <span style="color: #2e8b57;"><strong>const</strong></span> 型引用时自动转换为 <span style="color: #2e8b57;"><strong>const</strong></span><br />
非 <span style="color: #2e8b57;"><strong>const</strong></span> 对象的地址或指向非 <span style="color: #2e8b57;"><strong>const</strong></span> 对象的指针也可转换为指向 <span style="color: #2e8b57;"><strong>const</strong></span> 对象的指针<br />
⒉ 显式类型转换<br />
⑴ 若可能，避免使用强制类型转换<br />
确实需要使用时也应尽量小心<br />
⑵ 命名的强制类型转换<br />
① <span style="color: #804040;"><strong>dynamic_cast</strong></span><br />
用于运行时类型识别(RTTI)<br />
② <span style="color: #804040;"><strong>const_cast</strong></span><br />
可以添加或去除指针、数据成员指针或引用的 <span style="color: #2e8b57;"><strong>const</strong></span> 特性<br />
③ <span style="color: #804040;"><strong>static_cast</strong></span><br />
ⅰ 可以显式完成编译器隐式执行的任何类型转换<br />
因潜在精度损失产生的编译器警告会被关闭<br />
· 可以用以避免不必要的隐式转换，如<br />
已知 d 为 <span style="color: #2e8b57;"><strong>double</strong></span>, i 为 <span style="color: #2e8b57;"><strong>int</strong></span>, 将 i*=d; 写成 i*=<span style="color: #804040;"><strong>static_cast</strong></span>&lt;<span style="color: #2e8b57;"><strong>int</strong></span>&gt;(d); 可省去将 i 转换为 <span style="color: #2e8b57;"><strong>double</strong></span> 这一非必要步骤<br />
④ <span style="color: #804040;"><strong>reinterpret_cast</strong></span><br />
为操作数的位模式提供较低层次的重新解释，结果依赖编译器和机器<br />
任何不当使用都可能导致运行时错误<br />
⑶ 旧式强制转换<br />
在合法使用 <span style="color: #804040;"><strong>static_cast</strong></span> 或 <span style="color: #804040;"><strong>const_cast</strong></span> 的地方，提供与命名强制转换一样的功能<br />
若两种转换均不合法，就执行 <span style="color: #804040;"><strong>reinterpret_cast</strong></span><br />
由于不易判别每个显式转换的潜在风险，不推荐使用</p>

<hr/><blockquote><p>可能你对下面的文章也感兴趣：</p><ol>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter2/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第二章'>C++ Primer 读书笔记 &#8211; 第二章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter4/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第四章'>C++ Primer 读书笔记 &#8211; 第四章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter3/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第三章'>C++ Primer 读书笔记 &#8211; 第三章</a></li>
</ol></blockquote>]]></content:encoded>
			<wfw:commentRss>http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter5/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>C++ Primer 读书笔记 &#8211; 第四章</title>
		<link>http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter4/</link>
		<comments>http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter4/#comments</comments>
		<pubDate>Tue, 19 Aug 2008 17:17:47 +0000</pubDate>
		<dc:creator>逆铭</dc:creator>
				<category><![CDATA[新长征路上的代码]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[笔记]]></category>

		<guid isPermaLink="false">http://blog.tomtung.com/2008/08/c-primer-%e8%af%bb%e4%b9%a6%e7%ac%94%e8%ae%b0-%e7%ac%ac%e5%9b%9b%e7%ab%a0/</guid>
		<description><![CDATA[<a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter4/" title="C++ Primer 读书笔记 - 第四章"></a>[笔记索引] 第４章 数组和指针 现代C++程序应使用vector和迭代器代替数组和指针，除非前二者不满足对效率的特殊要求 ⒋⒈ 数组 ⒈ 数组是由类型说明符、标识符和维度组成的复合类型，能保存一组某种类型的未命名对象 ⒉ 定义和初始化 ⑴ 类型说明符规定了存放于数组中元素的类型 可使用除引用外的任意类型，包括数组本身(数组的数组即多维数组) ⑵ 维数指定数组中包含的元素个数，须用值大于等于1的常量表达式定义，一经指定不可改变 ⑶ 可以使用初值列表(用花括号括起的一组用逗号分隔的初值，可为空)显式提供元素的初值 ① 此时可不指定维数，数组长度将由初值列表中的元素个数自动确定 ② 若指定维数： ⅰ 维数值不能小于初值个数 ⅱ 若维数值大于初始化列表中提供的元素个数，则只用初值列表初始化数组中前面对应的元素 其余元素，若为内置类型则初始化为0，若为类类型则调用默认构造函数 ③ 对于多维数组，除第一维外其余维数都须显示指定 初值列表可内嵌花括号以指明各初值对应的位置，若不使用内嵌花括号则依次初始化 ⑷ 若未提供初值列表，则数组元素像普通变量一样初始化 ⑸ 使用字符串字面值初始化字符数组时注意前者结尾隐含的空字符 ⒊ 不允许数组直接复制和赋值 ⒋ 数组元素可通过下标操作符[]访问，下标从0开始 下标越界将导致运行时错误 ⒋⒉ 指针 &#8230;<p class="read-more"><a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter4/">继续阅读 &#187;</a></p><hr/><blockquote>
可能你对下面的文章也感兴趣：<ol>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter3/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第三章'>C++ Primer 读书笔记 &#8211; 第三章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter2/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第二章'>C++ Primer 读书笔记 &#8211; 第二章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-index/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 索引'>C++ Primer 读书笔记 &#8211; 索引</a></li>
</ol></blockquote>]]></description>
			<content:encoded><![CDATA[<a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter4/" title="C++ Primer 读书笔记 - 第四章"></a><p style="text-align: right;"><a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-index/" target="_blank"><span style="font-size: 12px;"> [笔记索引]</span></a></p>
<p><span style="font-size: 12px;">第４章 数组和指针<br />
现代C++程序应使用vector和迭代器代替数组和指针，除非前二者不满足对效率的特殊要求</span></p>
<p><span style="font-size: 12px;"> ⒋⒈ 数组<br />
⒈ 数组是由类型说明符、标识符和维度组成的复合类型，能保存一组某种类型的未命名对象<br />
⒉ 定义和初始化<br />
⑴ 类型说明符规定了存放于数组中元素的类型<br />
可使用除引用外的任意类型，包括数组本身(数组的数组即多维数组)<br />
⑵ 维数指定数组中包含的元素个数，须用值大于等于</span><span style="color: #ff00ff;">1</span>的常量表达式定义，一经指定不可改变<br />
⑶ 可以使用初值列表(用花括号括起的一组用逗号分隔的初值，可为空)显式提供元素的初值<br />
① 此时可不指定维数，数组长度将由初值列表中的元素个数自动确定<br />
② 若指定维数：<br />
ⅰ 维数值不能小于初值个数<br />
ⅱ 若维数值大于初始化列表中提供的元素个数，则只用初值列表初始化数组中前面对应的元素<br />
其余元素，若为内置类型则初始化为<span style="color: #ff00ff;">0</span>，若为类类型则调用默认构造函数<br />
③ 对于多维数组，除第一维外其余维数都须显示指定<br />
初值列表可内嵌花括号以指明各初值对应的位置，若不使用内嵌花括号则依次初始化<br />
⑷ 若未提供初值列表，则数组元素像普通变量一样初始化<br />
⑸ 使用字符串字面值初始化字符数组时注意前者结尾隐含的空字符<br />
⒊ 不允许数组直接复制和赋值<br />
⒋ 数组元素可通过下标操作符[]访问，下标从<span style="color: #ff00ff;">0</span>开始<br />
下标越界将导致运行时错误</p>
<p>⒋⒉ 指针<br />
⒈ 指针是一种能储存对象地址的对象<br />
⒉ 定义和初始化<br />
⑴ 形式： 类型名* 标识符;<br />
类型名指定指针指向对象的类型(类型名为 <span style="color: #2e8b57;"><strong>void</strong></span> 时指针可指向任意类型的对象)<br />
① 连续声明多个指针时，每个标识符前都要加*号<br />
② 可以连续使用多个星号*表示指向指针的指针<br />
③ <span style="color: #2e8b57;"><strong>const</strong></span> 限定符<br />
ⅰ 指向 <span style="color: #2e8b57;"><strong>const</strong></span> 对象的指针<br />
ａ形式： <span style="color: #2e8b57;"><strong>const</strong></span> 类型名* 标识符;<br />
（或 类型名 <span style="color: #2e8b57;"><strong>const</strong></span>* 标识符;）<br />
ｂ <span style="color: #2e8b57;"><strong>const</strong></span> 对象只能与这种指针关联<br />
ｃ不能通过这种指针修改所指对象，无论所指是否为 <span style="color: #2e8b57;"><strong>const</strong></span><br />
由于有此特性，该种指针常用作函数形参以防止所指对象被意外修改<br />
ⅱ <span style="color: #2e8b57;"><strong>const</strong></span> 指针<br />
ａ形式：类型名* <span style="color: #2e8b57;"><strong>const</strong></span> 标识符<br />
ｂ指针本身的值不能修改，即不能改变指向，但可以改变所指对象的值<br />
ⅲ 指向 <span style="color: #2e8b57;"><strong>const</strong></span> 对象的 <span style="color: #2e8b57;"><strong>const</strong></span> 指针<br />
ａ形式： <span style="color: #2e8b57;"><strong>const</strong></span> 类型名* <span style="color: #2e8b57;"><strong>const</strong></span> 标识符<br />
ｂ既不能改变所指对象的值，也不能改变指向<br />
ⅳ <span style="color: #2e8b57;"><strong>typedef</strong></span> T* pT; 则 <span style="color: #2e8b57;"><strong>const</strong></span> pT t 和 pT <span style="color: #2e8b57;"><strong>const</strong></span> t 均与 T* <span style="color: #2e8b57;"><strong>const</strong></span> t 等价<br />
④ 指向数组的指针<br />
ⅰ 形式： 类型名 (*标识符)[维数][维数]..[维数];<br />
ⅱ <span style="color: #2e8b57;"><strong>typedef</strong></span> 类型名新类型名[维数][维数]..[维数];<br />
得到数组类型的别名，可以此简化定义<br />
⑵ 应避免使用未初始化的指针<br />
而一个有效的指针必然为以下三种状态之一：<br />
① 保存某确定对象的地址<br />
② 指向一个对象的下一位置<br />
③ 值为<span style="color: #ff00ff;">0</span><br />
因此在对指针初始化和赋值时只能使用：<br />
① 值为<span style="color: #ff00ff;">0</span>的常量表达式<br />
② 类型匹配的对象的地址(使用取地址操作符&amp;获得,该运算符只能对左值使用)<br />
③ 另一对象下一位置的地址<br />
④ 同类型另一有效指针<br />
⒊ 指针操作<br />
⑴ 使用解引用操作符*可以获得指针指向对象的左值，从而操作所指对象<br />
而对指针直接进行赋值等操作将改变指针本身的值，使指针指向另一对象<br />
⑵ 指针可被当作数组的迭代器，用以访问数组元素<br />
① 指针的算术操作<br />
ⅰ 指针与整型值相加(减)，得到指向所指元素向后(前)移动相应位置的数组元素的新指针<br />
ⅱ 两个指向同一数组中元素的指针(含超出末端指针)相减，得到一个 <span style="color: #2e8b57;"><strong>ptrdiff_t</strong></span> 型(定义在头文件 cstddef 中， <span style="color: #2e8b57;"><strong>signed</strong></span> 整型)结果，表示两指针所指元素间的距离<br />
② 对指针进行下标操作[]，返回所指元素向后(前)移动相应位置的数组元素引用<br />
③ 可以计算超出末端指针，但不允许对其进行解引用操作<br />
计算越界指针也是非法的<br />
⑶ <span style="color: #2e8b57;"><strong>void</strong></span>* 指针不支持以上操作</p>
<p>⒋⒊ C风格字符串<br />
⒈ C风格字符串是以空字符结尾的字符数组<br />
字符串字面值就是其实例<br />
⒉ C风格字符串的标准库函数(头文件 cstring)<br />
传给以下库函数的须为指向以空字符结尾的字符数组的非零指针<br />
⑴ <span style="color: #2e8b57;"><strong>size_t</strong></span> strlen( <span style="color: #2e8b57;"><strong>char</strong></span> *str );<br />
返回字符串长度(不包括结尾的空字符)<br />
⑵ <span style="color: #2e8b57;"><strong>int</strong></span> strcmp( <span style="color: #2e8b57;"><strong>const</strong></span> <span style="color: #2e8b57;"><strong>char</strong></span> *str1, <span style="color: #2e8b57;"><strong>const</strong></span> <span style="color: #2e8b57;"><strong>char</strong></span> *str2 );<br />
比较两个字符串，如果前者大于后者返回正数，小于返回负数，等于返回<span style="color: #ff00ff;">0</span><br />
注：不能使用&gt;,&lt;,==操作符比较，它们只会比较存放地址而不会比较字符串<br />
⑶ <span style="color: #2e8b57;"><strong>char</strong></span> *strcat( <span style="color: #2e8b57;"><strong>char</strong></span> *str1, <span style="color: #2e8b57;"><strong>const</strong></span> <span style="color: #2e8b57;"><strong>char</strong></span> *str2 );<br />
将str2连接到str1后面，并返回str1<br />
此函数不进行越界检查<br />
⑷ <span style="color: #2e8b57;"><strong>char</strong></span> *strcpy( <span style="color: #2e8b57;"><strong>char</strong></span> *to, <span style="color: #2e8b57;"><strong>const</strong></span> <span style="color: #2e8b57;"><strong>char</strong></span> *from );<br />
将str2复制到str1字符串，并返回str1<br />
此函数不进行越界检查<br />
⑸ <span style="color: #2e8b57;"><strong>char</strong></span> *strncat( <span style="color: #2e8b57;"><strong>char</strong></span> *str1, <span style="color: #2e8b57;"><strong>const</strong></span> <span style="color: #2e8b57;"><strong>char</strong></span> *str2, <span style="color: #2e8b57;"><strong>size_t</strong></span> count );<br />
将str2的前至多count个字符连接到str1后面，并返回str1<br />
如果越界则截断字符串，因此比strcat安全<br />
⑹ <span style="color: #2e8b57;"><strong>char</strong></span> *strncpy( <span style="color: #2e8b57;"><strong>char</strong></span> *to, <span style="color: #2e8b57;"><strong>const</strong></span> <span style="color: #2e8b57;"><strong>char</strong></span> *from, <span style="color: #2e8b57;"><strong>size_t</strong></span> count );<br />
将str2的前至多count个字符复制到str1，并返回str1<br />
如果越界则截断字符串，因此比strcpy安全<br />
⒊ 对于大部分程序而言，标准库类型 string 无论安全性还是效率均强过C风格字符串，因此应尽可能使用 string</p>

<hr/><blockquote><p>可能你对下面的文章也感兴趣：</p><ol>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter3/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第三章'>C++ Primer 读书笔记 &#8211; 第三章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter2/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第二章'>C++ Primer 读书笔记 &#8211; 第二章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-index/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 索引'>C++ Primer 读书笔记 &#8211; 索引</a></li>
</ol></blockquote>]]></content:encoded>
			<wfw:commentRss>http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C++ Primer 读书笔记 &#8211; 第三章</title>
		<link>http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter3/</link>
		<comments>http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter3/#comments</comments>
		<pubDate>Tue, 12 Aug 2008 15:05:31 +0000</pubDate>
		<dc:creator>逆铭</dc:creator>
				<category><![CDATA[新长征路上的代码]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[笔记]]></category>

		<guid isPermaLink="false">http://blog.tomtung.com/2008/08/c-primer-%e8%af%bb%e4%b9%a6%e7%ac%94%e8%ae%b0-%e7%ac%ac%e4%b8%89%e7%ab%a0/</guid>
		<description><![CDATA[<a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter3/" title="C++ Primer 读书笔记 - 第三章"></a>[笔记索引] 第３章 标准库类型 ⒊⒌ 标准库bitset类型 [以下下标和位数均为 size_t 型(定义在头文件 cstddef 中， unsigned 整型)] ⒈ bitset 是一种类模板，用于保存位集，并提供测位和置位操作 ⒉ 定义和初始化 bitset 在定义时需要以常量表达式的形式提供位数N 初始化时参数提供位数不足则剩余高阶位置为0，位数过多则抛弃多余高阶位 ⑴ bitset&#60;N&#62; b; 默认构造函数置各位为0 ⑵ bitset&#60;N&#62; b( unsigned long u ); 使用 unsigned long 值u的二进制形式初始化 ⑶ bitset&#60;N&#62; b( string s, &#8230;<p class="read-more"><a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter3/">继续阅读 &#187;</a></p><hr/><blockquote>
可能你对下面的文章也感兴趣：<ol>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter2/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第二章'>C++ Primer 读书笔记 &#8211; 第二章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-index/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 索引'>C++ Primer 读书笔记 &#8211; 索引</a></li>
<li><a href='http://blog.tomtung.com/2007/06/c-cpp-io-odd-behavior/' rel='bookmark' title='诡异的事：关于C/C++输入输出'>诡异的事：关于C/C++输入输出</a></li>
</ol></blockquote>]]></description>
			<content:encoded><![CDATA[<a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter3/" title="C++ Primer 读书笔记 - 第三章"></a><p style="text-align: right;"><a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-index/" target="_blank"><span style="font-size: 12px;"> [笔记索引]</span></a></p>
<p><span style="font-size: 12px;">第３章 标准库类型</span></p>
<p><span style="font-size: 12px;"> ⒊⒌ 标准库bitset类型<br />
<strong>[以下下标和位数均为 <span style="color: #2e8b57;">size_t</span> 型(定义在头文件 cstddef 中， <span style="color: #339900;">unsigned</span> 整型)]</strong><br />
⒈ bitset 是一种类模板，用于保存位集，并提供测位和置位操作<br />
⒉ 定义和初始化<br />
bitset 在定义时需要以常量表达式的形式提供位数N<br />
初始化时参数提供位数不足则剩余高阶位置为</span><span style="color: #ff00ff;">0</span>，位数过多则抛弃多余高阶位<br />
⑴ bitset&lt;N&gt; b;<br />
默认构造函数置各位为<span style="color: #ff00ff;">0</span><br />
⑵ bitset&lt;N&gt; b( <span style="color: #2e8b57;"><strong>unsigned</strong></span> <span style="color: #2e8b57;"><strong>long</strong></span> u );<br />
使用 <span style="color: #2e8b57;"><strong>unsigned</strong></span> <span style="color: #2e8b57;"><strong>long</strong></span> 值u的二进制形式初始化<br />
⑶ bitset&lt;N&gt; b( string s, <span style="color: #2e8b57;"><strong>size_t</strong></span> pos=<span style="color: #ff00ff;">0</span> );<br />
bitset&lt;N&gt; b( string s, <span style="color: #2e8b57;"><strong>size_t</strong></span> pos, <span style="color: #2e8b57;"><strong>size_t</strong></span> m );<br />
使用 string 对象s或其(下标pos起到结尾或长度为m的)子串初始化<br />
(子)串最右端对应低阶(low-order)位，向左依次类推<br />
⒊ 操作<br />
除支持<strong>所有内置位运算符</strong>以及==和!=外，还支持以下操作:<br />
⑴ 访问整个 bitset 对象<br />
① <span style="color: #2e8b57;"><strong>bool</strong></span> any();<br />
返回是否各位不全为<span style="color: #ff00ff;">0</span><br />
② <span style="color: #2e8b57;"><strong>bool</strong></span> none();<br />
返回是否各位全为<span style="color: #ff00ff;">0</span><br />
③ <span style="color: #2e8b57;"><strong>size_t</strong></span> count();<br />
返回为<span style="color: #ff00ff;">1</span>的位的个数<br />
④ <span style="color: #2e8b57;"><strong>size_t</strong></span> size();<br />
返回能容纳的位数<br />
⑵ 访问 bitset 对象中的位<br />
(从低阶位起，各位编号依次为 <span style="color: #ff00ff;">0</span>, <span style="color: #ff00ff;">1</span>, <span style="color: #ff00ff;">2</span>, <span style="color: #ff00ff;">3</span> &#8230;)<br />
① 下标操作符[]返回指定位的引用<br />
② <span style="color: #2e8b57;"><strong>bool</strong></span> test( <span style="color: #2e8b57;"><strong>size_t</strong></span> pos );<br />
返回指定位的值<br />
③ bitset&lt;N&gt;&amp; set( <span style="color: #2e8b57;"><strong>size_t</strong></span> pos, <span style="color: #2e8b57;"><strong>int</strong></span> val=<span style="color: #ff00ff;">1</span> );<br />
设定指定位的值并返回对象的引用<br />
④ bitset&lt;N&gt;&amp; reset( <span style="color: #2e8b57;"><strong>size_t</strong></span> pos );<br />
清零指定位并返回对象的引用<br />
⑤ bitset&lt;N&gt;&amp; flip( <span style="color: #2e8b57;"><strong>size_t</strong></span> pos );<br />
取反特定位并返回对象的引用<br />
也可以b[pos].flip()，返回指定位的引用<br />
⑶ 设置整个 bitset 对象<br />
① bitset&lt;N&gt;&amp; set();<br />
置所有位为<span style="color: #ff00ff;">1</span>并返回对象的引用<br />
② bitset&lt;N&gt;&amp; reset();<br />
清零所有位并返回对象的引用<br />
③ bitset&lt;N&gt;&amp; flip();<br />
取反所有位并返回对象的引用<br />
⑷ 获取 bitset 对象的值<br />
① <span style="color: #2e8b57;"><strong>unsigned</strong></span> <span style="color: #2e8b57;"><strong>long</strong></span> to_ulong();<br />
返回位模式相同的 <span style="color: #2e8b57;"><strong>unsigned</strong></span> <span style="color: #2e8b57;"><strong>long</strong></span> 值<br />
若越界则产生运行时异常<br />
② string to_string();<br />
返回字符串形式<br />
③ 可使用输出操作符打印 bitset 对象</p>

<hr/><blockquote><p>可能你对下面的文章也感兴趣：</p><ol>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter2/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 第二章'>C++ Primer 读书笔记 &#8211; 第二章</a></li>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-index/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 索引'>C++ Primer 读书笔记 &#8211; 索引</a></li>
<li><a href='http://blog.tomtung.com/2007/06/c-cpp-io-odd-behavior/' rel='bookmark' title='诡异的事：关于C/C++输入输出'>诡异的事：关于C/C++输入输出</a></li>
</ol></blockquote>]]></content:encoded>
			<wfw:commentRss>http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>C++ Primer 读书笔记 &#8211; 第二章</title>
		<link>http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter2/</link>
		<comments>http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter2/#comments</comments>
		<pubDate>Thu, 07 Aug 2008 15:06:22 +0000</pubDate>
		<dc:creator>逆铭</dc:creator>
				<category><![CDATA[新长征路上的代码]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[笔记]]></category>

		<guid isPermaLink="false">http://blog.tomtung.com/2008/08/c-primer-%e8%af%bb%e4%b9%a6%e7%ac%94%e8%ae%b0-%e7%ac%ac%e4%ba%8c%e7%ab%a0/</guid>
		<description><![CDATA[<a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter2/" title="C++ Primer 读书笔记 - 第二章"></a>[笔记索引] 第２章 变量和基本类型 ⒉⒈ 基本内置类型 ⒈ 算数类型(arithmetic types)：表示数值(即整数和浮点数)的类型 ⒉⒈⒈ 整型 ⒈ 整型(Integral Types)：表示整数、字符和布尔值的算数类型。包括： ⑴ char: 字符型，通常单个机器字节，最小8位 wchar_t: 宽字符型，最小16位 用于扩展字符集，如汉字和日语 ⑵ short: 短整型，通常半个字长，最小16位 由于范围较小容易越界，执行整型算数运算时很少使用 int: 整型，通常1个字长，最小16位，大多数机器使用32位表示 用于整型运算时不易出错 long: 长整型，通常1或2个机器字长，最小32位 对用32位表示 int 而用64位表示 long 的机器，后者代价远高于前者，使用时如何选择应视情况而定 ⑶ bool: 布尔型，赋值时0值算数类型为 false, 其余为 true ⒉ &#8230;<p class="read-more"><a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter2/">继续阅读 &#187;</a></p><hr/><blockquote>
可能你对下面的文章也感兴趣：<ol>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-index/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 索引'>C++ Primer 读书笔记 &#8211; 索引</a></li>
<li><a href='http://blog.tomtung.com/2007/06/c-cpp-io-odd-behavior/' rel='bookmark' title='诡异的事：关于C/C++输入输出'>诡异的事：关于C/C++输入输出</a></li>
</ol></blockquote>]]></description>
			<content:encoded><![CDATA[<a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter2/" title="C++ Primer 读书笔记 - 第二章"></a><p style="text-align: right;"><a href="http://blog.sina.com.cn/s/blog_4a443fd70100aq4s.html" target="_blank"><span style="font-size: 12px;"> </span></a><span style="font-size: 12px;">[<a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-index/">笔记索引</a>]</span></p>
<p><span style="font-size: 12px;">第２章 变量和基本类型</span></p>
<p><span style="font-size: 12px;"> ⒉⒈ 基本内置类型<br />
⒈ 算数类型(arithmetic types)：表示数值(即整数和浮点数)的类型</span></p>
<p><span style="font-size: 12px;"> ⒉⒈⒈ 整型<br />
⒈ 整型(Integral Types)：表示整数、字符和布尔值的算数类型。包括：<br />
⑴ </span><span style="color: #2e8b57;"><strong>char</strong></span>: 字符型，通常单个机器字节，最小<span style="color: #ff00ff;">8</span>位<br />
<span style="color: #804040;"><strong>wchar_t</strong></span>:<br />
宽字符型，最小<span style="color: #ff00ff;">16</span>位<br />
用于扩展字符集，如汉字和日语<br />
⑵ <span style="color: #2e8b57;"><strong>short</strong></span>:<br />
短整型，通常半个字长，最小<span style="color: #ff00ff;">16</span>位<br />
由于范围较小容易越界，执行整型算数运算时很少使用<br />
<span style="color: #804040;"><strong>int</strong></span>:<br />
整型，通常<span style="color: #ff00ff;">1</span>个字长，最小<span style="color: #ff00ff;">16</span>位，大多数机器使用<span style="color: #ff00ff;">32</span>位表示<br />
用于整型运算时不易出错<br />
<span style="color: #804040;"><strong>long</strong></span>:<br />
长整型，通常<span style="color: #ff00ff;">1</span>或<span style="color: #ff00ff;">2</span>个机器字长，最小<span style="color: #ff00ff;">32</span>位<br />
对用<span style="color: #ff00ff;">32</span>位表示 <span style="color: #2e8b57;"><strong>int</strong></span> 而用<span style="color: #ff00ff;">64</span>位表示 <span style="color: #2e8b57;"><strong>long</strong></span> 的机器，后者代价远高于前者，使用时如何选择应视情况而定<br />
⑶ <span style="color: #2e8b57;"><strong>bool</strong></span>:<br />
布尔型，赋值时<span style="color: #ff00ff;">0</span>值算数类型为 <span style="color: #ff00ff;">false</span>, 其余为 <span style="color: #ff00ff;">true</span><br />
⒉ 带符号(<span style="color: #2e8b57;"><strong>signed</strong></span>)和无符号(<span style="color: #2e8b57;"><strong>unsigned</strong></span>)类型<br />
⑴ 带符号类型可以表示正数、<span style="color: #ff00ff;">0</span>和负数; 无符号只能表示非负数<br />
⑵ <span style="color: #2e8b57;"><strong>int</strong></span>,<span style="color: #2e8b57;"><strong>short</strong></span>,<span style="color: #2e8b57;"><strong>long</strong></span> 都默认为 <span style="color: #2e8b57;"><strong>signed</strong></span><br />
⑶ <span style="color: #2e8b57;"><strong>char</strong></span> 有<span style="color: #ff00ff;">3</span>种不同类型: 普通, <span style="color: #2e8b57;"><strong>unsigned</strong></span>, <span style="color: #2e8b57;"><strong>signed</strong></span>, 但只有<span style="color: #ff00ff;">2</span>种表示方式<br />
<span style="color: #2e8b57;"><strong>char</strong></span> 使用哪一种表示方式由编译器决定<br />
⒊ 整型值的表示<br />
⑴ <span style="color: #2e8b57;"><strong>unsigned</strong></span> 型中，所有位都用来表示数值<br />
⑵ <span style="color: #2e8b57;"><strong>signed</strong></span> 型如何用位由编译器决定。常见策略为使用其中一个位作符号位，该位为<span style="color: #ff00ff;">1</span>则值为负，为<span style="color: #ff00ff;">0</span>则值为<span style="color: #ff00ff;">0</span>或正<br />
⒋ 将一个越界值赋给一个指定类型的变量时：<br />
⑴ 若类型为 <span style="color: #2e8b57;"><strong>unsigned</strong></span>, 编译器通过对越界值取模来满足要求<br />
⑵ 若类型为 <span style="color: #2e8b57;"><strong>signed</strong></span>, 行为未定义</p>
<p>⒉⒈⒉ 浮点型<br />
⑴ <span style="color: #2e8b57;"><strong>float</strong></span>:<br />
单精度浮点数，一般一个字长，最小<span style="color: #ff00ff;">6</span>位有效数字<br />
其可能的精度损失不可忽视<br />
⑵ <span style="color: #2e8b57;"><strong>double</strong></span>:<br />
双精度浮点数，一般两个字长，最小<span style="color: #ff00ff;">10</span>位有效数字<br />
其计算代最小<span style="color: #ff00ff;">8</span>位价与 <span style="color: #2e8b57;"><strong>float</strong></span> 相当，使用它基本不会错<br />
⑶ <span style="color: #2e8b57;"><strong>long</strong></span> <span style="color: #2e8b57;"><strong>double</strong></span>:<br />
扩展精度浮点数，一般三或四个字长，最小<span style="color: #ff00ff;">10</span>位有效数字<br />
其提供的额外精度往往无必要，且需承担额外的运行代价</p>
<p>⒉⒉ 字面值常量<br />
⒈ 整数字面值<br />
⑴ 定义字面值整型常量可以使用十进制、八进制(以<span style="color: #ff00ff;">0</span>开头表示)和十六进制(以0x或0X开头表示)中的任意一种<br />
⑵ 默认为 <span style="color: #2e8b57;"><strong>int</strong></span> 或 <span style="color: #2e8b57;"><strong>long</strong></span> 型(值适合 <span style="color: #2e8b57;"><strong>int</strong></span> 就为 <span style="color: #2e8b57;"><strong>int</strong></span> 型，比 <span style="color: #2e8b57;"><strong>int</strong></span> 大最小<span style="color: #ff00ff;">8</span>位就为 <span style="color: #2e8b57;"><strong>long</strong></span> 型)<br />
⑶ 数值后加上后缀 U, L, UL 分别表示 <span style="color: #2e8b57;"><strong>unsigned</strong></span>, <span style="color: #2e8b57;"><strong>long</strong></span>, <span style="color: #2e8b57;"><strong>unsigned</strong></span> <span style="color: #2e8b57;"><strong>long</strong></span><br />
⒉ 浮点数字面值<br />
⑴ 可以使用普通的十进制表示法或科学计数法表示。使用后者时，用E或e来标示指数<br />
⑵ 默认为 <span style="color: #2e8b57;"><strong>double</strong></span> 型<br />
⑶ 数值后加上后缀 F, L 分别表示 <span style="color: #2e8b57;"><strong>float</strong></span>, <span style="color: #2e8b57;"><strong>long</strong></span> <span style="color: #2e8b57;"><strong>double</strong></span><br />
⒊ 布尔字面值: <span style="color: #ff00ff;">true</span>, <span style="color: #ff00ff;">false</span><br />
⒋ 字符字面值<br />
⑴ 通过用单引号引起的字符或转义字符定义<br />
⑵ 前面加上L表示wchar_t型<br />
⑶ C++中定义的转义字符有：<br />
\&#8217; 单引号<br />
\<span style="color: #ff00ff;">&#8221; 双引号</span><br />
\\ 反斜杠<br />
\<span style="color: #ff00ff;">0</span> 空字符<br />
\a 响铃<br />
\b 后退<br />
\f 走纸<br />
\n 换行<br />
\r 回车<br />
\t 水平制表符<br />
\v 垂直制表符<br />
\oct 编号为oct的字符(oct表示一个八进制数，不必以<span style="color: #ff00ff;">0</span>开头)<br />
\xhex 编号为hex的字符(hex表示一个十六进制数，不以0x或0X开头)<br />
⒌ 字符串字面值<br />
⑴ 通过用双引号引起的若干个字符或转义字符定义<br />
⑵ 类型为以 <span style="color: #ff00ff;">NULL</span> 结束的 <span style="color: #2e8b57;"><strong>const</strong></span> <span style="color: #2e8b57;"><strong>char</strong></span> 型数组(结尾的空字符由编译器自动添加)<br />
⑶ 前面加上L表示宽字符串面值<br />
⑷ 两个相邻的仅由空格、制表符或换行符分开的(宽)字符串面值，可连接成一个新(宽)字符串字面值<br />
这一特性可用于处理长字符串字面值<br />
试图连接一个字符串字面值和一个宽字符串字面值将导致未定义行为<br />
⑸ C++代码中，在一行末尾加反斜线符号(其后不可再出现空格或注释)可将该行与下一行当作同一行处理(因此第二行可能不允许有正常的缩进)<br />
这一特性也可用于处理长字符串字面值，但并不常用</p>
<p>⒉⒊ 变量<br />
⒈ 左值(lvalue)和右值(rvalue)<br />
⑴ 左值：可以出现在赋值操作的左边或右边的值。非 <span style="color: #2e8b57;"><strong>const</strong></span> 左值可读可写。<br />
⑵ 右值：可以出现在赋值操作右边但不能出现在左边的值。可读不可写。<br />
变量是左值<br />
⒉ 变量名，可由字母或下划线开头，用字母、数字和下划线组成；大小写敏感<br />
⒊ 变量的定义<br />
⑴ 变量的定义为变量分配存储空间，还能同时指定其初始值。在程序中，一个变量有且仅有一个定义<br />
⑵ 变量的初始化<br />
① 提供初始化式时，支持两种初始化形式：<br />
a. 复制初始化：用等号(=) (注:不是赋值)<br />
b. 直接初始化：将初始化式放在括号中；更灵活，效率更高<br />
对内置类型而言，二者几乎没有差别；对类类型而言，有时必须用后者<br />
② 不提供初始化式：<br />
a. 对内置类型变量：在函数体外定义的自动初始化为<span style="color: #ff00ff;">0</span>，在函数体内定义的不进行自动初始化<br />
b. 对类类型变量：若该类提供默认构造函数则调用它，否则必须提供显式初始化式<br />
③ 同时定义多个变量时，以上各种初始化形式(包括不提供初始化式)都可混用；可以用同一定义中前面已定义变量的值给后面的变量初始化<br />
⑶ 在变量首次使用处定义变量往往能增加代码可读性，减少开销<br />
⒋ 变量的声明<br />
⑴ 变量的声明向程序表明变量的类型和名字。声明可以在程序中出现多次。定义也是声明<br />
⑵ 使用 <span style="color: #2e8b57;"><strong>extern</strong></span> 关键字可声明一个变量而不定义它，常用于使数据横跨多个文件的作用域<br />
⑶ 若声明有初始化式，则被当作定义，即使使用了 <span style="color: #2e8b57;"><strong>extern</strong></span> 关键字也一样<br />
⑷ 在全局作用域中定义的非 <span style="color: #2e8b57;"><strong>const</strong></span> 对象在整个程序的各个文件中都可见，只要在其它文件中声明它就可以访问；<br />
但全局作用域中的 <span style="color: #2e8b57;"><strong>const</strong></span> 对象默认为其定义所在文件的局部对象，只有在定义前指定它为 <span style="color: #2e8b57;"><strong>extern</strong></span> 才能在其它文件中访问</p>
<p>⒉⒊⒍ 名字的作用域<br />
⒈ 作用域(scope)：程序的一部分，名字在其中有意义。<br />
C++中的作用域有以下几种：<br />
⑴ 全局：名字定义在任何其他作用域外<br />
⑵ 类：名字由类定义<br />
⑶ 命名空间：名字在命名空间中定义<br />
⑷ 局部：名字在函数中定义<br />
⑸ 块：名字定义在语句块中(即定义在一对花括号里)<br />
⑹ 语句：名字在语句(如 <span style="color: #804040;"><strong>if</strong></span> 、 <span style="color: #804040;"><strong>while</strong></span> 、 <span style="color: #804040;"><strong>for</strong></span> 语句)的条件内定义<br />
⒉ 作用域可嵌套，外层作用域的名字在内层可见。内层作用域中的名字可以屏蔽(hide)外层中同样的</p>
<p>⒉⒌ 引用<br />
⒈ 引用(reference)是一种复合类型(即用其它类型定义的类型)，表示另一个(非引用)对象的别名，对它的所有操作都直接作用在该对象上<br />
引用主要用作函数形参<br />
⒉ 引用定义格式为<br />
类型名&amp; 标识符<br />
( 数组的引用定义格式： 类型名 (&amp;标识符)[维度]<br />
指针的引用定义格式： 类型名*&amp; 标识符         )<br />
同时定义多个引用时每个引用的标识符前都要加&amp;(以及[维度]和*)<br />
定义引用必须用对应类型的对象初始化，表示绑定到该对象，且一经绑定不可更改<br />
⒊ <span style="color: #2e8b57;"><strong>const</strong></span> 引用是只读的，可以绑定到不同但相关类型的对象，也可绑定到右值；<br />
非 <span style="color: #2e8b57;"><strong>const</strong></span> 对象只能绑定到与该引用同类型的对象</p>
<p>⒉⒍ 定义类型名<br />
⒈ <span style="color: #2e8b57;"><strong>typedef</strong></span> 用于定义一个类型的同义词。定义格式为：<br />
<span style="color: #2e8b57;"><strong>typedef</strong></span> 类型 标识符;<br />
⒉ 常为以下<span style="color: #ff00ff;">3</span>种目的使用 <span style="color: #2e8b57;"><strong>typedef</strong></span> :<br />
⑴ 隐藏特定类型实现，强调使用类型的目的<br />
⑵ 精简类型定义以便理解<br />
⑶ 多次使用同一类型，保持每次使用目的明确</p>
<p>⒉⒎ 枚举<br />
⒈ 枚举(enumeration)类型由一组枚举成员(enumerator)组成<br />
其中每个枚举成员都有自己的名字，初始化为整型 <span style="color: #2e8b57;"><strong>const</strong></span> 值(值可重复，但初始化后不能修改)<br />
⒉ 定义格式： <span style="color: #2e8b57;"><strong>enum</strong></span> 枚举类型名 {用逗号分开的枚举成员列表};<br />
可以用常量表达式通过赋值操作符为列表中某些枚举成员提供初始值，未提供初值的默认每个值比前一个大<span style="color: #ff00ff;">1</span>(第一个默认为<span style="color: #ff00ff;">0</span>)<br />
⒊ 每个 <span style="color: #2e8b57;"><strong>enum</strong></span> 都唯一定义一种类型，枚举类型的对象初始化或赋值时只能通过该类型的枚举成员或另一对象进行</p>
<p>⒉⒐ 头文件<br />
⒈ 因为头文件包含在多个源文件中，故一般只应包含对象和函数的声明而不包含定义，但以下除外：<br />
⑴ 类<br />
⑵ 用常量表达式初始化的 <span style="color: #2e8b57;"><strong>const</strong></span> 对象<br />
(若不是用常量表达式初始化，则应和其它对象一样在一个文件中定义并初始化，并在头文件中添加 <span style="color: #2e8b57;"><strong>extern</strong></span> 声明以便多文件共享)<br />
⑶ <span style="color: #2e8b57;"><strong>inline</strong></span> 函数<br />
以上都可以在多个文件中定义(只要定义一致)。需要在头文件定义是因为编译器需要它们的定义来产生代码<br />
⒉ 预处理器<br />
⑴ #include 只接受一个头文件名作为参数<br />
头文件名在尖括号中被认为是标准头文件，编译器将在预定义位置查找<br />
头文件名在引号中被认为是非系统头文件，通常在源文件所在位置查找<br />
⑵ 可使用预处理器定义头文件保护符(header guard)避免多重包含，如：<br />
<span style="color: #a020f0;"> #ifndef XXX_HEADER_H</span><br />
<span style="color: #a020f0;"> #define XXX_HEADER_H</span><br />
<span style="color: #0000ff;">// 头文件内容，包括类等的定义</span><br />
<span style="color: #a020f0;"> #endif</span></p>

<hr/><blockquote><p>可能你对下面的文章也感兴趣：</p><ol>
<li><a href='http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-index/' rel='bookmark' title='C++ Primer 读书笔记 &#8211; 索引'>C++ Primer 读书笔记 &#8211; 索引</a></li>
<li><a href='http://blog.tomtung.com/2007/06/c-cpp-io-odd-behavior/' rel='bookmark' title='诡异的事：关于C/C++输入输出'>诡异的事：关于C/C++输入输出</a></li>
</ol></blockquote>]]></content:encoded>
			<wfw:commentRss>http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter2/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>C++ Primer 读书笔记 &#8211; 索引</title>
		<link>http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-index/</link>
		<comments>http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-index/#comments</comments>
		<pubDate>Thu, 07 Aug 2008 01:31:31 +0000</pubDate>
		<dc:creator>逆铭</dc:creator>
				<category><![CDATA[新长征路上的代码]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[笔记]]></category>

		<guid isPermaLink="false">http://blog.tomtung.com/2008/08/c-primer-%e8%af%bb%e4%b9%a6%e7%ac%94%e8%ae%b0-%e5%86%99%e5%9c%a8%e5%89%8d%e9%9d%a2%e6%9b%b4%e6%96%b0%e7%b4%a2%e5%bc%95/</guid>
		<description><![CDATA[<a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-index/" title="C++ Primer 读书笔记 - 索引"></a>终于开始读第二遍了……开始真没把这书当回事。搞OI的时候一直是用 C++ 的（当然是作为 a better C ……当然不包括STL……），C++ 的教材也读过（顺便Orz下谭老师），觉得写程序就是算法比较麻烦，语言只是个基础，随随便便就搞定了。这书是年初买的，当时还想着一个月看完呢，结果，呃，断断续续拖了仨月到高考前才看完第一遍。C++ 里各种各样的功能及细节一时让我觉得自己在备考地理历史或是别的什么文科课程…… 这本书我觉得和CLRS很像。书名都非常谦虚（一个叫 Primer 一个叫 Introduction），都比书名暗示的要厚、难，虽然没有特别 tricky 的内容却贵在全面，如果能够掌握对付一般情况都绰绰有余。 在读第一遍的时候我就已经做了比较粗略的笔记，现在重新整理一下。所有帮助理解的辅助内容都尽量被剔除，为了帮助理解而做的顺序调整也被恢复，使得关键点以更结构化的形式组织起来。我希望有了整理的笔记就可以抛开原书（去BUAA实在不想带这书，太沉了- -）。 笔记中很多基础点可能会因为之前就已经熟知而被忽略。这个笔记并不适合初学者。它适合： 1. 我自己——这是做笔记的主要目的 2. 看过全书希望迅速浏览各个关键点来复习的同学 3. 已经读过别的 C++ 书籍不知道此书是否还值得一读的同学 4. 希望能借助别人的笔记加工出自己的 ……………… 恩……笔记会以章为单位放出，已经放出的内容也可能被修改。如果发现任何错误、遗漏、啰嗦等不妥的地方，欢迎指正。 笔记会放在新分类“新长征路上的代码”中。之前关于OI的分类不再更新。 &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;菜菜的分割线&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; 笔记索引 第二章 - 基本内置类型字面值常量变量作用域引用(包括指针的引用、数组的引用) 枚举 第三章 - bitset &#8230;<p class="read-more"><a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-index/">继续阅读 &#187;</a></p><hr/><blockquote>
可能你对下面的文章也感兴趣：<ol>
<li><a href='http://blog.tomtung.com/2007/06/c-cpp-io-odd-behavior/' rel='bookmark' title='诡异的事：关于C/C++输入输出'>诡异的事：关于C/C++输入输出</a></li>
</ol></blockquote>]]></description>
			<content:encoded><![CDATA[<a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-index/" title="C++ Primer 读书笔记 - 索引"></a><p><a href="http://www.douban.com/subject/1767741/"><img style="padding-right: 20px; padding-left: 0px; float: left; padding-bottom: 20px; padding-top: 0px;" src="http://otho.douban.com/mpic/s1638975.jpg" alt="" /></a><a href="http://www.douban.com/subject/1415354/"><img style="padding-right: 20px; padding-left: 0px; float: left; padding-bottom: 20px; padding-top: 0px;" src="http://otho.douban.com/mpic/s2391721.jpg" alt="" /></a> 终于开始读第二遍了……开始真没把这书当回事。搞OI的时候一直是用 C++ 的（当然是作为 a better C ……当然不包括STL……），C++ 的教材也读过（顺便Orz下谭老师），觉得写程序就是算法比较麻烦，语言只是个基础，随随便便就搞定了。这书是年初买的，当时还想着一个月看完呢，结果，呃，断断续续拖了仨月到高考前才看完第一遍。C++ 里各种各样的功能及细节一时让我觉得自己在备考地理历史或是别的什么文科课程……<br />
这本书我觉得和CLRS很像。书名都非常谦虚（一个叫 Primer 一个叫 Introduction），都比书名暗示的要厚、难，虽然没有特别 tricky 的内容却贵在全面，如果能够掌握对付一般情况都绰绰有余。<br />
在读第一遍的时候我就已经做了比较粗略的笔记，现在重新整理一下。所有帮助理解的辅助内容都尽量被剔除，为了帮助理解而做的顺序调整也被恢复，使得关键点以更结构化的形式组织起来。我希望有了整理的笔记就可以抛开原书（去BUAA实在不想带这书，太沉了- -）。</p>
<p>笔记中很多基础点可能会因为之前就已经熟知而被忽略。这个笔记并不适合初学者。它适合：</p>
<p>1. 我自己——这是做笔记的主要目的</p>
<p>2. 看过全书希望迅速浏览各个关键点来复习的同学</p>
<p>3. 已经读过别的 C++ 书籍不知道此书是否还值得一读的同学</p>
<p>4. 希望能借助别人的笔记加工出自己的</p>
<p>………………</p>
<p>恩……笔记会以章为单位放出，已经放出的内容也可能被修改。如果发现任何错误、遗漏、啰嗦等不妥的地方，欢迎指正。</p>
<p>笔记会放在新分类“新长征路上的代码”中。之前关于OI的分类不再更新。</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;菜菜的分割线&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<pre><span style="font-size: 12px;">笔记索引</span>

<a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter2/" target="_blank"><span style="font-size: 12px;">第二章</span></a><span style="font-size: 12px;"> - 基本内置类型字面值常量变量作用域引用</span><span style="color: #999999;">(包括指针的引用、数组的引用)</span> 枚举

<a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter3/" target="_blank"><span style="font-size: 12px;">第三章</span></a><span style="font-size: 12px;"> - bitset </span><span style="color: #999999;">(vector、string和迭代器放到第九章和第十一章)</span>

<a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter4/" target="_blank"><span style="font-size: 12px;">第四章</span></a><span style="font-size: 12px;"> - 数组</span><span style="color: #999999;">(动态数组放到第五章new和delete表达式部分)</span> <span style="font-size: 12px;">C风格字符串</span>

<span style="font-size: 12px;">        指针</span><span style="font-size: 12px; color: #999999;">(包括指向数组的指针，不包括第七章的函数指针)</span>

<a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter5/" target="_blank"><span style="font-size: 12px;">第五章</span></a> <span style="font-size: 12px;">- 操作符(结合性、优先级)</span><span style="color: #999999;">(不包括与作用域,RTTI,成员指针,异常等有关操作符)</span>

<span style="color: #000000;">        表达式</span> 类型转换(显式、隐式)

<span style="font-size: 12px;"><a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter6/" target="_blank">第六章</a> - 语句</span><span style="color: #999999;">(与异常处理有关的内容放到第十七章；不包括第七章return语句)</span>

        使用预处理器调试

<span style="font-size: 12px;"><a href="http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-chapter7/" target="_blank"><span style="font-size: 12px;">第七章</span></a> - 函数</span><span style="color: #999999;">(类成员函数放到第十二章)</span>

<span style="font-size: 12px;"><a href="http://blog.tomtung.com/2008/09/cpp-primer-reding-notes-chapter8/" target="_blank"><span style="font-size: 12px;">第八章</span></a> - 标准IO库</span><span style="color: #999999;">(包括附录3中的所有内容)</span>

（停止更新）
</pre>

<hr/><blockquote><p>可能你对下面的文章也感兴趣：</p><ol>
<li><a href='http://blog.tomtung.com/2007/06/c-cpp-io-odd-behavior/' rel='bookmark' title='诡异的事：关于C/C++输入输出'>诡异的事：关于C/C++输入输出</a></li>
</ol></blockquote>]]></content:encoded>
			<wfw:commentRss>http://blog.tomtung.com/2008/08/cpp-primer-reding-notes-index/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>诡异的事：关于C/C++输入输出</title>
		<link>http://blog.tomtung.com/2007/06/c-cpp-io-odd-behavior/</link>
		<comments>http://blog.tomtung.com/2007/06/c-cpp-io-odd-behavior/#comments</comments>
		<pubDate>Fri, 15 Jun 2007 09:58:20 +0000</pubDate>
		<dc:creator>逆铭</dc:creator>
				<category><![CDATA[OI那一年]]></category>
		<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://blog.tomtung.com/2007/06/%e8%af%a1%e5%bc%82%e7%9a%84%e4%ba%8b%ef%bc%9a%e5%85%b3%e4%ba%8ecc%e8%be%93%e5%85%a5%e8%be%93%e5%87%ba-6-17%e6%9b%b4%e6%96%b0/</guid>
		<description><![CDATA[<a href="http://blog.tomtung.com/2007/06/c-cpp-io-odd-behavior/" title="诡异的事：关于C/C++输入输出"></a>今天做题做不进去，就想着学了C的输入输出吧，毕竟我一直使用C++的stream太慢了，一般考数据结构的题都是上百万的数据需要输入输出。记得看到一道题直接注明类似“给使用C++同学的提示：极限数据中使用流将比使用stdio.h中的输入输出函数多花1s时间”。这样学习C的stdio 就显得很必要了。但是今天出现了诡异的问题。 我们看到，慢得出名的stream竟然比C的I/O快？！反复运行都是这个结果，只是程度有所不同……而且不仅仅是这个程序，我把cashier的输入输出改了以后速度也没提高。太诡异了…… 下面帖出代码，大家帮忙看看是不是我写得不对 &#8211; - #include &#60;iostream&#62; #include &#60;fstream&#62; #include &#60;cstdio&#62; #include &#60;ctime&#62; using namespace std; int main() { printf("用C函数输出1000,0000个数花费时间为："); clock_t b=clock(); FILE *out = fopen("test.txt","w"); for(unsigned i=0;i&#60;10000000;i++) fprintf(out,"%d ",i); fclose(out); printf("%dms\n",clock()-b); cout &#60;&#60; "用stream输出1000,0000个数花费时间为："; clock_t a = clock(); &#8230;<p class="read-more"><a href="http://blog.tomtung.com/2007/06/c-cpp-io-odd-behavior/">继续阅读 &#187;</a></p>]]></description>
			<content:encoded><![CDATA[<a href="http://blog.tomtung.com/2007/06/c-cpp-io-odd-behavior/" title="诡异的事：关于C/C++输入输出"></a><div>
<div>今天做题做不进去，就想着学了C的输入输出吧，毕竟我一直使用C++的stream太慢了，一般考数据结构的题都是上百万的数据需要输入输出。记得看到一道题直接注明类似“给使用C++同学的提示：极限数据中使用流将比使用stdio.h中的输入输出函数多花1s时间”。这样学习C的stdio 就显得很必要了。但是今天出现了诡异的问题。</div>
<div><img class="alignnone" title="http://upload.tomtung.com/img/c-cpp-io-odd-behavior-win.jpg" src="http://upload.tomtung.com/img/c-cpp-io-odd-behavior-win.jpg" alt="" width="371" height="120" /></div>
<div>我们看到，慢得出名的stream竟然比C的I/O快？！反复运行都是这个结果，只是程度有所不同……而且不仅仅是这个程序，我把cashier的输入输出改了以后速度也没提高。太诡异了……</div>
<div>下面帖出代码，大家帮忙看看是不是我写得不对 &#8211; -</div>
<pre class="brush:c++">#include &lt;iostream&gt;
#include &lt;fstream&gt;
#include &lt;cstdio&gt;
#include &lt;ctime&gt;
using namespace std;
int main()
{
        printf("用C函数输出1000,0000个数花费时间为：");
        clock_t b=clock();
        FILE *out = fopen("test.txt","w");
        for(unsigned i=0;i&lt;10000000;i++)       fprintf(out,"%d ",i);
        fclose(out);
        printf("%dms\n",clock()-b);

        cout &lt;&lt; "用stream输出1000,0000个数花费时间为：";
        clock_t a = clock();
        ofstream fout("test.txt");
        for(unsigned i=0;i&lt;10000000;i++)       fout &lt;&lt; i &lt;&lt; ' ';
        fout.close();
        cout &lt;&lt; clock()-a &lt;&lt; "ms" &lt;&lt; endl;

        printf("用C函数读入1000,0000个数花费时间为：");
        clock_t c = clock();
        FILE *in = fopen("test.txt","r");
        for(unsigned i=0,j;i&lt;10000000;i++)  fscanf(in,"%u ",&amp;j);
        fclose(in);
        printf("%dms\n",clock()-c);

        printf("用stream读入1000,0000个数花费时间为：");
        clock_t d = clock();
        ifstream fin("test.txt");
        for(unsigned i=0,j;i&lt;10000000;i++)  fin &gt;&gt; j;
        fin.close();
        cout &lt;&lt; clock()-d &lt;&lt; "ms\n";

        system("pause");
}
</pre>
<div>update at 6.17:</div>
<div>下面是我今天(6.17)日在ubuntu下用anjuta&amp;g++做的测试情况。（忘了指明，上面的测试是在winXP下用devc++&amp;g++做的。）</div>
<div>几乎完全一样的代码（结果的显示格式稍做了变化），但结果完全不同。fstream的劣势很明显了。</div>
<p><img class="alignnone" title="http://upload.tomtung.com/img/c-cpp-io-odd-behavior-linux.png" src="http://upload.tomtung.com/img/c-cpp-io-odd-behavior-linux.png" alt="" width="589" height="442" /></p>
<div>鱼牛本来的解释是“我们平常说stream慢是指iostream，不是fstream”，看来也不尽然了。</div>
</div>

]]></content:encoded>
			<wfw:commentRss>http://blog.tomtung.com/2007/06/c-cpp-io-odd-behavior/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

