<?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>勿慢牛 &#187; c++ primer</title>
	<atom:link href="http://klniu.com/post/tag/c-primer/feed/" rel="self" type="application/rss+xml" />
	<link>http://klniu.com</link>
	<description>『勿慢牛个人博客』</description>
	<lastBuildDate>Fri, 06 Jan 2012 06:42:54 +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>c++ primer知识点－第6章 语句</title>
		<link>http://klniu.com/post/c-primer-knowledge-6/</link>
		<comments>http://klniu.com/post/c-primer-knowledge-6/#comments</comments>
		<pubDate>Sat, 03 Jan 2009 12:27:52 +0000</pubDate>
		<dc:creator>勿慢牛</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[c++ primer]]></category>

		<guid isPermaLink="false">http://livesdrop.com/2009/01/c-primer-knowledge-6/</guid>
		<description><![CDATA[目录 6.1 简单语句 6.2 声明语句 6.3 复合语句（块） 6.4 语句作用域 6.5 if语句 6.6 switch语句 6.7 while语句 6.8 for循环语句 6.9 do while语句 6.10 break语句 6.11 continue语句 6.12 goto语句 6.13 try块和异常处理 6.14 使用预处理器进行测试 &#160; 6.1 简单语句 &#160; C++中，大多数语句以分号结束。 6.2 声明语句 6.3 复合语句 　　复合语句，通常被称为块，是用一对花括号括起来的语句序列。块标识了一个作用域，在块中引入的名字只能在该块内部或嵌套在块中的子块里访问。 &#8230; <a href="http://klniu.com/post/c-primer-knowledge-6/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>目录</p>
<p>6.1 简单语句</p>
<p>6.2 声明语句</p>
<p>6.3 复合语句（块）</p>
<p>6.4 语句作用域</p>
<p>6.5 if语句</p>
<p>6.6 switch语句</p>
<p>6.7 while语句</p>
<p>6.8 for循环语句</p>
<p>6.9 do while语句</p>
<p>6.10 break语句</p>
<p>6.11 continue语句</p>
<p>6.12 goto语句</p>
<p>6.13 try块和异常处理</p>
<p>6.14 使用预处理器进行测试</p>
<p>&nbsp;</p>
<p>6.1 简单语句</p>
<p>&nbsp; C++中，大多数语句以分号结束。</p>
<p>6.2 声明语句</p>
<p>6.3 复合语句</p>
<p>　　复合语句，通常被称为块，是用一对花括号括起来的语句序列。块标识了一个作用域，在块中引入的名字只能在该块内部或嵌套在块中的子块里访问。</p>
<p>6.4 语句作用域</p>
<p>　　有些语句允许在它们的控制结构中定义变量，但仅在定义它们的块语句结束前有效，其作用域局限在语句内部。</p>
<pre class="prettyprint">
while (int i =get_num())
	cout &lt;&lt; i &lt;&lt; endl;
i = 0; //error: i is not accessable outside the loop</pre>
<p>6.5 if语句</p>
<p>　　if语句的条件表达式可以是初始化声明语句，其中，变量必须初始化，因为已初始化的变更值要转换为bool值用于判断。</p>
<p>6.6 switch语句</p>
<p>6.6.1 使用switch</p>
<p>　　如果条件表达式与其中一个标号的值匹配，则程序将从该标号后面的第一个语句开始依次执行各个语句，直到switch结束或遇到break语句为止。</p>
<p>6.6.2 switch中的控制流</p>
<p>　　为了安全起见，最好在每个后面提供一个break语句，即使是最后一个标号也一样。如果希望省略；case后面的break语句，可以将几个case语句写在一行，可以令代码更加清晰。</p>
<p>6.6.3 default标号</p>
<p>　　如果所有的case标号与switch表达式的值都不匹配，并且default标号存在，则执行default标号后面的语句。</p>
<p>6.6.4 switch表达式与case标号</p>
<p>　　switch求解表达式可以是定义和初始化一个变量。</p>
<pre class="prettyprint">
switch(int ival = get_response());</pre>
<p>ival的值将要与每个case标号比较。</p>
<p>6.6.5 switch内部的变量定义</p>
<p>　　在switch内部，要为某个特殊的case定义变量，则可以引入块语句，在该语句中定义变量，从而保证这个变量在使用前被定义和初始化。</p>
<p>6.7 while语句</p>
<p>　　while循环内的赋值操作是一种常见的用法。</p>
<p>6.8 for循环语句</p>
<p>　　应该谨记：在for语句头定义的任何对象限制在for循环体里可见。</p>
<p>6.8.1 省略语句头的某些部分</p>
<p>　　可以省略初始化语句、循环语句和表达式中的任何一个，但是分号不能省略。</p>
<p>6.8.2 for语句头中的多个定义</p>
<p>　　可以在for语句的初始化语句中定义多个对象，但是不管怎么样，该处只能出现一个语句，因此所有的对象必须具有相同的一般类型。</p>
<p>6.9 do while语句</p>
<p>6.10 break语句</p>
<p>　　break用于结束最近的while、do while、for或switch语句，并将程序的执行权传递给紧接在被终止语句之后的语句。break只能出现在循环或switch结构中，或者出现在嵌套于循环或switch结构中的语句里。</p>
<p>6.11 continue语句</p>
<p>　　continue语句导致最近的循环语句的当次迭代提前结束。对于while和do while语句，继续求解循环条件，而对于for循环，程序流程接着求解for语句头中的expression表达式。</p>
<p>6.12 goto语句</p>
<p>　　尽量不要使用。</p>
<p>6.13 try块和异常处理</p>
<p>　　C++的异常处理包括：</p>
<p>1. throw表达式，错误检测部分使用这种表达式来说明遇到了不可处理的错误。</p>
<p>2. try块，错误处理部分使用它来处理异常。try语句块以try关键字开始，并以一个或多个catch子句结束。在try块中执行的代码所抛出的异常，通常会被其中一个catch子句处理。</p>
<p>3. 由标准库定义的一组异常类，用来在throw和相应的catch之间传递有关的错误信息。</p>
<p>6.13.1 throw表达式</p>
<p>　　系统通过throw表达式抛出异常。throw表达式由关键字throw以及尾随的表达式组成，通常以分号结束。</p>
<p>6.13.2 try块</p>
<p>　　try块的通用语法形式是：</p>
<pre class="prettyprint">
try {
    program-statements
} catch (exception-specifier) {
    handler-statements
} catch (exception-specifier) {
    handler-statements
}</pre>
<p>1. 编写处理代码</p>
<p>2. 函数在寻找处理代码的过程中退出</p>
<p>　　寻找处理代码的过程与函数调用链刚好相反。抛出一个异常时，首先要搜索的是抛出异常的函数。如果没有找到匹配的 catch，则终止这个函数的执行，并在调用这个函数的函数中寻找相配的 catch。如果仍然找到相应的处理代码，该函数同样要终止，搜索调用它的函数。如此类推，继续按执行路径回退，直到找到适当类型的 catch 为止。<br />
如果不存在处理该异常的 catch 子句，程序的运行就要跳转到名为 terminate 的标准库函数，该函数在 exception 头文件中定义。这个标准库函数的行为依赖于系统，通常情况下，它的执行将导致程序非正常退出。<br />
在程序中出现的异常，如果没有经 try 块定义，则都以相同的方式来处理：毕竟，如果没有任何 try 块，也就没有捕获异常的处理代码（catch 子句）。此时，如果发生了异常，系统将自动调用 terminate 终止程序的执行。</p>
<p>6.13.3 标准异常</p>
<p>　　C++标准库定义了一组类，用于报告在标准库中的函数遇到的问题。</p>
<p>1. exception头文件定义了最常见的异常类，它的类名是exception。这个类只通知异常的产生，但不会提供更多的信息。</p>
<p>2. stdexcept头文件定义了几种常见的异常类。表中列出了头文件中定义的标准异常类。</p>
<table width="607" cellspacing="10" cellpadding="2" border="0">
<tbody>
<tr>
<td width="200" valign="top">exception</td>
<td width="375" valign="top">最常见的问题</td>
</tr>
<tr>
<td width="200" valign="top">runtime_error</td>
<td width="375" valign="top">运行时错误：仅在运行时才能检测到的问题</td>
</tr>
<tr>
<td width="200" valign="top">range_error</td>
<td width="375" valign="top">运行时错误：生成的结果超出了有意义的值域范围</td>
</tr>
<tr>
<td width="200" valign="top">overflow_error</td>
<td width="375" valign="top">运行时错误：计算上溢</td>
</tr>
<tr>
<td width="200" valign="top">underflow_error</td>
<td width="375" valign="top">运行时错误：计算下溢</td>
</tr>
<tr>
<td width="200" valign="top">logic_error</td>
<td width="375" valign="top">逻辑错误：可在运行前检测到的问题</td>
</tr>
<tr>
<td width="200" valign="top">domain_error</td>
<td width="375" valign="top">逻辑错误：参数的结果值不存在</td>
</tr>
<tr>
<td width="200" valign="top">ivalid_argument</td>
<td width="375" valign="top">逻辑错误：不合适的参数</td>
</tr>
<tr>
<td width="200" valign="top">length_error</td>
<td width="375" valign="top">逻辑错误：试图生成一个超出该类型最大长度的对象</td>
</tr>
<tr>
<td width="200" valign="top">out_of_range</td>
<td width="375" valign="top">逻辑错误：使用一个超出有效范围的值</td>
</tr>
</tbody>
</table>
<p>6.14 使用预处理器进行调试</p>
<p>　　可用NDEBUG预处理变量实现有条件的调试代码：</p>
<pre class="prettyprint">
int mian()
{
  #ifndef NDEBUG
    cerr &lt;&lt; &quot;starting main&quot; &lt;&lt; endl;
  #endl
  //...</pre>
<p>&nbsp;</p>
<p>开发完成后，可通过定义NDEBUG预处理变量，删除这些调试语句。</p>
<p>　　预处理器还定义了其余四种在调试时非常有用的常量：</p>
<p>_ _FILE_ _ 文件名</p>
<p>_ _LINE_ _ 当前行号</p>
<p>_ _TIME_ _ 文件被编译的时间</p>
<p>_ _DATE_ _ 文件被编译的日期</p>
<pre class="prettyprint">
if (word.size() &lt; threshold)
    cerr &lt;&lt; &quot;Error: &quot; &lt;&lt; _ _FILE_ _
         &lt;&lt; &quot; :line &quot; &lt;&lt; _ _LINE_ _ &lt;&lt; endl
         &lt;&lt; &quot;       Compiled on &quot; &lt;&lt; _ _DATE_ _
         &lt;&lt; &quot; at &quot; &lt;&lt; _ _TIME_ _ &lt;&lt; endl
         &lt;&lt; &quot;       Word read was &quot; &lt;&lt; word
         &lt;&lt; &quot;:  LENGTH too shor&quot; &lt;&lt; endl;</pre>
<p>　　另一种调试技术是使用NDEBUG预处理变量以及asset(断言)预处理宏。assert宏是在cassert头文件中定义的。</p>
<pre class="prettyprint">
assert(expr)</pre>
<p>&nbsp;</p>
<p>　　只要NDEBUG未定义，assert宏就求解条件表达式expr，如果结果为false，assert输出信息并且终止程序的执行。如果该表达式有一个非零值，则assert不做任何操作。在测试过程中，assert等效于检验数据是否总是具有预期的大小，一旦程序完成，并且定义了NDEBUG，assert语句就不做任何工作。assert仅用于检查确实不可能的条件。</p>
]]></content:encoded>
			<wfw:commentRss>http://klniu.com/post/c-primer-knowledge-6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>c++ primer知识点－第5章 表达式</title>
		<link>http://klniu.com/post/c-primer-knowledge-5/</link>
		<comments>http://klniu.com/post/c-primer-knowledge-5/#comments</comments>
		<pubDate>Fri, 02 Jan 2009 14:52:21 +0000</pubDate>
		<dc:creator>勿慢牛</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[c++ primer]]></category>

		<guid isPermaLink="false">http://livesdrop.com/2009/01/c-primer-knowledge-5/</guid>
		<description><![CDATA[目录 5.1 算术操作符 5.2 关系操作符和逻辑操作符 5.3 位操作符 5.4 赋值操作符 5.5 自增和自减操作符 5.6 箭头操作符 5.7 条件操作符 5.8 sizeof操作符 5.9 逗号操作符 5.10 复合表达式的求值 5.11 new和delete表达式 5.12 类型转换 &#160; 表达式由一个或多个操作数通过操作符组合而成，每个表达式都会产生一个结果。 5.1 算术操作符 算术操作符（优先级相同时，操作符从左向右结合） 操作符 功能 + 一元正号 - 一元负号 * 乘法 / 除法 &#8230; <a href="http://klniu.com/post/c-primer-knowledge-5/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>目录</p>
<p>5.1 算术操作符</p>
<p>5.2 关系操作符和逻辑操作符</p>
<p>5.3 位操作符</p>
<p>5.4 赋值操作符</p>
<p>5.5 自增和自减操作符</p>
<p>5.6 箭头操作符</p>
<p>5.7 条件操作符</p>
<p>5.8 sizeof操作符</p>
<p>5.9 逗号操作符</p>
<p>5.10 复合表达式的求值</p>
<p>5.11 new和delete表达式</p>
<p>5.12 类型转换</p>
<p>&nbsp;</p>
<p>表达式由一个或多个操作数通过操作符组合而成，每个表达式都会产生一个结果。</p>
<p>5.1 算术操作符</p>
<blockquote><p>算术操作符（优先级相同时，操作符从左向右结合）</p>
</blockquote>
<table cellspacing="10" cellpadding="2" width="400" border="0">
<tbody>
<tr>
<td valign="top" width="200">操作符</td>
<td valign="top" width="200">功能</td>
</tr>
<tr>
<td valign="top" width="200">+</td>
<td valign="top" width="200">一元正号</td>
</tr>
<tr>
<td valign="top" width="200">-</td>
<td valign="top" width="200">一元负号</td>
</tr>
<tr>
<td valign="top" width="200">*</td>
<td valign="top" width="200">乘法</td>
</tr>
<tr>
<td valign="top" width="200">/</td>
<td valign="top" width="200">除法</td>
</tr>
<tr>
<td valign="top" width="200">%</td>
<td valign="top" width="200">求余</td>
</tr>
<tr>
<td valign="top" width="200">+</td>
<td valign="top" width="200">加法</td>
</tr>
<tr>
<td valign="top" width="200">-</td>
<td valign="top" width="200">减法</td>
</tr>
</tbody>
</table>
<p>%只能用于整数，包括bool，char，short，int和long类型，以及对应的unsigned类型。</p>
<p>5.2 关系操作符和逻辑操作符</p>
<table cellspacing="10" cellpadding="2" width="400" border="0">
<tbody>
<tr>
<td valign="top" width="100">!</td>
<td valign="top" width="100">逻辑非</td>
<td valign="top" width="100">&lt;</td>
<td valign="top" width="100">小于</td>
</tr>
<tr>
<td valign="top" width="100">&lt;=</td>
<td valign="top" width="100">小于等于</td>
<td valign="top" width="100">&gt;</td>
<td valign="top" width="100">大于</td>
</tr>
<tr>
<td valign="top" width="100">&gt;=</td>
<td valign="top" width="100">大于等于</td>
<td valign="top" width="100">==</td>
<td valign="top" width="100">相等</td>
</tr>
<tr>
<td valign="top" width="100">!=</td>
<td valign="top" width="100">不等</td>
<td valign="top" width="100">&amp;&amp;</td>
<td valign="top" width="100">逻辑与</td>
</tr>
<tr>
<td valign="top" width="100">||</td>
<td valign="top" width="100">逻辑或</td>
<td valign="top" width="100">&nbsp;</td>
<td valign="top" width="100">&nbsp;</td>
</tr>
</tbody>
</table>
<p>1. 逻辑与、逻辑或操作符</p>
<p>短路求值；如果某边界条件使expr2的计算变得危险，则就应在该条件出现之前，先让expr1的计算结果为false。</p>
<p>2. 逻辑非操作符</p>
<p>3. 不应该串接使用关系操作符</p>
<p>4. 相等测试与bool字面值</p>
<p>直接用变量作为条件进行检测（可以转换为bool类型）</p>
<p>5.3 位操作符</p>
<p>位操作符使用整型的操作数。位操作符将其整型操作数视为二进制位的集合，为每一位提供检验和设置功能，还可用于bitset类型。</p>
<table cellspacing="10" cellpadding="2" width="400" border="0">
<tbody>
<tr>
<td valign="top" width="100">~</td>
<td valign="top" width="100">位求反</td>
<td valign="top" width="100">&lt;&lt;</td>
<td valign="top" width="100">左移</td>
</tr>
<tr>
<td valign="top" width="100">&gt;&gt;</td>
<td valign="top" width="100">右移</td>
<td valign="top" width="100">&amp;</td>
<td valign="top" width="100">位与</td>
</tr>
<tr>
<td valign="top" width="100">^</td>
<td valign="top" width="100">位异或</td>
<td valign="top" width="100">|</td>
<td valign="top" width="100">位或</td>
</tr>
</tbody>
</table>
<p>对于位操作符，系统不能确保如何处理其操作数的符号位，因些强烈建议使用unsigned整数。</p>
<p>&gt;&gt;和&lt;&lt;操作符提供移位操作，其右操作数标志要移动的位数；左移操作符&lt;&lt;在右边插入0以补充空位；对于右移操作符&gt;&gt;，如果其操作数是无符号数，则从左边开始插入0；如果是有符号数，则插入符号位的副本或者0值。移位操作符的右操作数不可为负。</p>
<p>位与操作符&amp;需要两个整型操作数，在每个位的位置，如果两个操作数对应的位都为1，则操作数结果中该位为1，否则为0。</p>
<p>位异或操作符^需要两个整型操作数，在每个位的位置，只有一个位为1，则操作数结果中该位为1，否则为0。</p>
<p>位或操作符|需要两个整型操作数，在每个位的位置，有一个或两个位为1，则操作数结果中该位为1，否则为0。</p>
<p>5.3.1 bitset对象或整型值的使用</p>
<p>设置第27位为1，其他为0。</p>
<pre>bitset&lt;30&gt; bitset_quizl; <span style="color: rgb(0,128,0)">//bitset solution</span>
<span style="color: rgb(0,0,255)">unsigned</span> <span style="color: rgb(0,0,255)">long</span> int_quizl = 0; <span style="color: rgb(0,128,0)">//simulated collection of bits</span>
bitset_quizl.set(27); <span style="color: rgb(0,128,0)">//inside student number 27 passed</span>
int_quizl |= 1UL &lt;&lt; 27;</pre>
<p>重新设置第27位为0；</p>
<pre>bitset_quizl.reset(27);
int_quizl &amp;= -(1UL &lt;&lt; 27);</pre>
<p>5.3.2 将移位操作符用于IO</p>
<p>IO操作符为左结合。</p>
<p>5.4 赋值操作符</p>
<p>赋值操作符的左操作数必须是非const的左值；赋值表达式的值是其左操作数的值，其结果的类型为左操作数的类型。</p>
<p>5.4.1 赋值操作的右结合性</p>
<pre>ival = jval = 0; <span style="color: rgb(0,128,0)">//从右向左结合</span></pre>
<p>5.4.2 赋值操作具有低优先级</p>
<p>谨防混淆相等操作符和赋值操作符。</p>
<p>5.4.3 复合赋值操作符</p>
<pre>a op = b; <span style="color: rgb(0,128,0)">//op 可以是以下操作符之一: +=, -=, *=, /=, %=, &lt;&lt;=, &gt;&gt;=, |=, ^=</span></pre>
<p>5.5 自增和自减操作符</p>
<p>只有必要时才使用后置操作符（前置操作符效率更高）。</p>
<p>1. 后置操作符返回未加1的值。</p>
<p>2. 在单个表达式中组合使用解引用和自增操作</p>
<pre>*iter++; <span style="color: rgb(0,128,0)">//解引用操作*的操作九是iter未加1前的副本。</span></pre>
<p>5.6 箭头操作符</p>
<p>点操作符用于获取类类型对象的成员；如果有一个指向Sales_item对象的指针(或迭代器)，则在使用点操作符前，需对该指针(或)迭代器进行解引用。</p>
<pre>(*sp).Sales_item(item2); <span style="color: rgb(0,128,0)">//注意不要丢掉()</span></pre>
<p>当然可以用-&gt;代替*</p>
<pre>sp-&gt;.Sales_item(item2); <span style="color: rgb(0,128,0)">//就不用()了</span></pre>
<p>5.7 条件操作符</p>
<p>唯一的三元操作符。</p>
<pre>cond ? exp1 : exp2;</pre>
<p>1. 避免条件操作符的深度嵌套</p>
<pre><span style="color: rgb(0,0,255)">int</span> max = i &gt; j
		? i &gt; k ? i : k
		: j &gt; k ? j :k; <span style="color: rgb(0,128,0)">//--&gt;</span>
<span style="color: rgb(0,0,255)">int</span> max = i;
<span style="color: rgb(0,0,255)">if</span> (j &gt; max)
   max = j;
<span style="color: rgb(0,0,255)">if</span> (k &gt; max)
   max = k;</pre>
<p>2. 在输出表达式中使用条件操作符</p>
<p>条件操作符的优先级相当低，如果有一个更强大的表达式嵌入条件表达式时，通常必须用圆括号把条件表达式括起来。</p>
<p>5.8 sizeof操作符</p>
<p>sizeof操作符的作用是返回一个对象或类型名的长度，返回值的类型为size_t，长度的单位是字节。</p>
<pre><span style="color: rgb(0,0,255)">sizeof</span> (type name);
<span style="color: rgb(0,0,255)">sizeof</span> (expr);<span style="color: rgb(0,128,0)">//将sizeof应用在表达式expr上，将获得该表达式的结果的类型长度</span>
<span style="color: rgb(0,0,255)">sizeof</span> expr;<span style="color: rgb(0,128,0)">//the same as above</span></pre>
<p>将sizeof用于expr时，并没有计算表达式expr的值。特别是在sizeof *p中，指针p可以持有一个无效地址，因为不需要对p做解引用操作。</p>
<p>使用sizeof的结果部分地依赖所涉及的类型：</p>
<p>(1) 对char类型或值为char类型的表达式做sizeof操作保证得1。</p>
<p>(2) 对引用类型做sizeof操作将返回存放此引用类型对象所需的内存空间大小。</p>
<p>(3) 对指针做sizeof操作将返回存放指针所需的内存大小；注意，如果要获取该指针所指向对象的大小，则必须对该指针进行解引用。</p>
<p>(4) 对数组做sizeof操作等效于将对其元素类型做sizeof操作的结果乘上数组元素的个数。</p>
<p>5.9 逗号操作符</p>
<p>从左向右计算，结果是其最右边的表达式。</p>
<p>5.10 复合表达式的求值</p>
<p>5.10.1 优先级</p>
<p>5.10.2 结合性</p>
<p>赋值操作有右结合性，这个特性允许将多个赋值操作串接起来。</p>
<pre class="prettyprint">ival = jval = kval = lval</pre>
<p>
<center></p>
<p>表 5.4. 操作符的优先级</p>
<p></center></p>
<table cellspacing="0" cellpadding="5" rules="groups" border="1">
<colgroup>
<col width="50">
<col width="100">
<col width="350">
<col width="150">
<col width="50"></colgroup>
<thead>
<tr>
<th valign="top" scope="col" align="middle" colspan="2">
<p>Associativity</p>
<p>and Operator</p>
<p>操作符及其结合性</p>
</th>
<th valign="top" scope="col" align="middle">
<p>Function</p>
<p>功能</p>
</th>
<th valign="top" scope="col" align="middle">
<p>Use</p>
<p>用法</p>
</th>
<th valign="top" scope="col" align="middle">
<p>See</p>
<p>Page</p>
<p>参见页码</p>
</th>
</tr>
</thead>
<tbody>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>::</tt></p>
</td>
<td valign="top" align="left">
<p>global scope（全局作用域）</p>
</td>
<td valign="top" align="left">
<p><tt>::</tt> name</p>
</td>
<td valign="top" align="right">
<p>p. 450</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>::</tt></p>
</td>
<td valign="top" align="left">
<p>class scope（类作用域）</p>
</td>
<td valign="top" align="left">
<p>class <tt>::</tt> name</p>
</td>
<td valign="top" align="right">
<p>p. 85</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>::</tt></p>
</td>
<td valign="top" align="left">
<p>namespace scope（名字空间作用域）</p>
</td>
<td valign="top" align="left">
<p>namespace <tt>::</tt> name</p>
</td>
<td valign="top" align="right">
<p>p. 78</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>.</tt></p>
</td>
<td valign="top" align="left">
<p>member selectors（成员选择）</p>
</td>
<td valign="top" align="left">
<p>object <tt>.</tt> member</p>
</td>
<td valign="top" align="right">
<p>p. 25</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>-&gt;</tt></p>
</td>
<td valign="top" align="left">
<p>member selectors（成员选择）</p>
</td>
<td valign="top" align="left">
<p>pointer <tt>-&gt;</tt> member</p>
</td>
<td valign="top" align="right">
<p>p. 164</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>[]</tt></p>
</td>
<td valign="top" align="left">
<p>subscript（下标）</p>
</td>
<td valign="top" align="left">
<p>variable <tt>[</tt> expr <tt>]</tt></p>
</td>
<td valign="top" align="right">
<p>p. 113</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>()</tt></p>
</td>
<td valign="top" align="left">
<p>function call（函数调用）</p>
</td>
<td valign="top" align="left">
<p>name <tt>(</tt>expr_list<tt>)</tt></p>
</td>
<td valign="top" align="right">
<p>p. 25</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>()</tt></p>
</td>
<td valign="top" align="left">
<p>type construction（类型构造）</p>
</td>
<td valign="top" align="left">
<p>type <tt>(</tt>expr_list<tt>)</tt></p>
</td>
<td valign="top" align="right">
<p>p. 460</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>++</tt></p>
</td>
<td valign="top" align="left">
<p>postfix increment（后自增操作）</p>
</td>
<td valign="top" align="left">
<p>lvalue<tt>++</tt></p>
</td>
<td valign="top" align="right">
<p>p. 162</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>--</tt></p>
</td>
<td valign="top" align="left">
<p>postfix decrement（后自减操作）</p>
</td>
<td valign="top" align="left">
<p>lvalue<tt>--</tt></p>
</td>
<td valign="top" align="right">
<p>p. 162</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>typeid</tt></p>
</td>
<td valign="top" align="left">
<p>type ID（类型 ID）</p>
</td>
<td valign="top" align="left">
<p><tt>typeid (</tt>type<tt>)</tt></p>
</td>
<td valign="top" align="right">
<p>p. 775</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>typeid</tt></p>
</td>
<td valign="top" align="left">
<p>run-time type ID（运行时类型 ID）</p>
</td>
<td valign="top" align="left">
<p><tt>typeid (</tt>expr<tt>)</tt></p>
</td>
<td valign="top" align="right">
<p>p. 775</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p>explicit cast（显式强制类型转换）</p>
</td>
<td valign="top" align="left">
<p>type conversion（类型转换）</p>
</td>
<td valign="top" align="left">
<p><span>cast_name</span> &lt;type&gt;(expr)</p>
</td>
<td valign="top" align="right">
<p>p. 183</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>sizeof</tt></p>
</td>
<td valign="top" align="left">
<p>size of object（对象的大小）</p>
</td>
<td valign="top" align="left">
<p><tt>sizeof</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 167</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>sizeof</tt></p>
</td>
<td valign="top" align="left">
<p>size of type（类型的大小）</p>
</td>
<td valign="top" align="left">
<p><tt>sizeof</tt>(type)</p>
</td>
<td valign="top" align="right">
<p>p. 167</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>++</tt></p>
</td>
<td valign="top" align="left">
<p>prefix increment（前自增操作）</p>
</td>
<td valign="top" align="left">
<p><tt>++</tt> lvalue</p>
</td>
<td valign="top" align="right">
<p>p. 162</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>--</tt></p>
</td>
<td valign="top" align="left">
<p>prefix decrement（前自减操作）</p>
</td>
<td valign="top" align="left">
<p><tt>--</tt> lvalue</p>
</td>
<td valign="top" align="right">
<p>p. 162</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>~</tt></p>
</td>
<td valign="top" align="left">
<p>bitwise NOT（位求反）</p>
</td>
<td valign="top" align="left">
<p><tt>~</tt>expr</p>
</td>
<td valign="top" align="right">
<p>p. 154</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>!</tt></p>
</td>
<td valign="top" align="left">
<p>logical NOT（逻辑非）</p>
</td>
<td valign="top" align="left">
<p><tt>!</tt>expr</p>
</td>
<td valign="top" align="right">
<p>p. 152</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>-</tt></p>
</td>
<td valign="top" align="left">
<p>unary minus（一元负号）</p>
</td>
<td valign="top" align="left">
<p><tt>-</tt>expr</p>
</td>
<td valign="top" align="right">
<p>p. 150</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>+</tt></p>
</td>
<td valign="top" align="left">
<p>unary plus（一元正号）</p>
</td>
<td valign="top" align="left">
<p><tt>+</tt>expr</p>
</td>
<td valign="top" align="right">
<p>p. 150</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>*</tt></p>
</td>
<td valign="top" align="left">
<p>dereference（解引用）</p>
</td>
<td valign="top" align="left">
<p><tt>*</tt>expr</p>
</td>
<td valign="top" align="right">
<p>p. 119</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>&amp;</tt></p>
</td>
<td valign="top" align="left">
<p>address-of（取地址）</p>
</td>
<td valign="top" align="left">
<p><tt>&amp;</tt>expr</p>
</td>
<td valign="top" align="right">
<p>p. 115</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>()</tt></p>
</td>
<td valign="top" align="left">
<p>type conversion（类型转换）</p>
</td>
<td valign="top" align="left">
<p>(type) expr</p>
</td>
<td valign="top" align="right">
<p>p. 186</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>new</tt></p>
</td>
<td valign="top" align="left">
<p>allocate object（创建对象）</p>
</td>
<td valign="top" align="left">
<p><tt>new</tt> type</p>
</td>
<td valign="top" align="right">
<p>p. <a href="#ch05sb16">174</a></p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>delete</tt></p>
</td>
<td valign="top" align="left">
<p>deallocate object（释放对象）</p>
</td>
<td valign="top" align="left">
<p><tt>delete</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 176</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>delete[]</tt></p>
</td>
<td valign="top" align="left">
<p>deallocate array（释放数组）</p>
</td>
<td valign="top" align="left">
<p><tt>delete[]</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 137</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>-&gt;*</tt></p>
</td>
<td valign="top" align="left">
<p>ptr to member select（指向成员操作的指针）</p>
</td>
<td valign="top" align="left">
<p>ptr <tt>-&gt;*</tt> ptr_to_member</p>
</td>
<td valign="top" align="right">
<p>p. 783</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>.*</tt></p>
</td>
<td valign="top" align="left">
<p>ptr to member select（指向成员操作的指针）</p>
</td>
<td valign="top" align="left">
<p>obj <tt>.*</tt>ptr_to_member</p>
</td>
<td valign="top" align="right">
<p>p. 783</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>*</tt></p>
</td>
<td valign="top" align="left">
<p>multiply（乘法）</p>
</td>
<td valign="top" align="left">
<p>expr <tt>*</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 149</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>/</tt></p>
</td>
<td valign="top" align="left">
<p>divide（除法）</p>
</td>
<td valign="top" align="left">
<p>expr <tt>/</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 149</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>%</tt></p>
</td>
<td valign="top" align="left">
<p>modulo (remainder)（求模（求余））</p>
</td>
<td valign="top" align="left">
<p>expr <tt>%</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 149</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>+</tt></p>
</td>
<td valign="top" align="left">
<p>add（加法）</p>
</td>
<td valign="top" align="left">
<p>expr <tt>+</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 149</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>-</tt></p>
</td>
<td valign="top" align="left">
<p>subtract（减法）</p>
</td>
<td valign="top" align="left">
<p>expr <tt>-</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 149</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>&lt;&lt;</tt></p>
</td>
<td valign="top" align="left">
<p>bitwise shift left（位左移）</p>
</td>
<td valign="top" align="left">
<p>expr <tt>&lt;&lt;</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 154</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>&gt;&gt;</tt></p>
</td>
<td valign="top" align="left">
<p>bitwise shift right（位右移）</p>
</td>
<td valign="top" align="left">
<p>expr <tt>&gt;&gt;</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 154</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>&lt;</tt></p>
</td>
<td valign="top" align="left">
<p>less than（小于）</p>
</td>
<td valign="top" align="left">
<p>expr <tt>&lt;</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 152</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>&lt;=</tt></p>
</td>
<td valign="top" align="left">
<p>less than or equal（小于或等于）</p>
</td>
<td valign="top" align="left">
<p>expr <tt>&lt;=</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 152</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>&gt;</tt></p>
</td>
<td valign="top" align="left">
<p>greater than（大于）</p>
</td>
<td valign="top" align="left">
<p>expr <tt>&gt;</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 152</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>&gt;=</tt></p>
</td>
<td valign="top" align="left">
<p>greater than or equal（大于或等于）</p>
</td>
<td valign="top" align="left">
<p>expr <tt>&gt;=</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 152</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>==</tt></p>
</td>
<td valign="top" align="left">
<p>equality（相等）</p>
</td>
<td valign="top" align="left">
<p>expr <tt>==</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 152</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>!=</tt></p>
</td>
<td valign="top" align="left">
<p>inequality（不等）</p>
</td>
<td valign="top" align="left">
<p>expr <tt>!=</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 152</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>&amp;</tt></p>
</td>
<td valign="top" align="left">
<p>bitwise AND（位与）</p>
</td>
<td valign="top" align="left">
<p>expr <tt>&amp;</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 154</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>^</tt></p>
</td>
<td valign="top" align="left">
<p>bitwise XOR（）</p>
</td>
<td valign="top" align="left">
<p>expr <tt>^</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 154</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>|</tt></p>
</td>
<td valign="top" align="left">
<p>bitwise OR（位异或）</p>
</td>
<td valign="top" align="left">
<p>expr <tt>|</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 154</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>&amp;&amp;</tt></p>
</td>
<td valign="top" align="left">
<p>logical AND（逻辑与）</p>
</td>
<td valign="top" align="left">
<p>expr <tt>&amp;&amp;</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 152</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>||</tt></p>
</td>
<td valign="top" align="left">
<p>logical OR（逻辑或）</p>
</td>
<td valign="top" align="left">
<p>expr <tt>||</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 152</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>?:</tt></p>
</td>
<td valign="top" align="left">
<p>conditional（条件操作）</p>
</td>
<td valign="top" align="left">
<p>expr <tt>?</tt> expr <tt>:</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 165</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>=</tt></p>
</td>
<td valign="top" align="left">
<p>assignment（赋值操作）</p>
</td>
<td valign="top" align="left">
<p>lvalue <tt>=</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 159</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>*=, /=, %=</tt>,</p>
</td>
<td valign="top" align="left">
<p>compound assign（复合赋值操作）</p>
</td>
<td valign="top" align="left">
<p>lvalue <tt>+=</tt> expr, etc.</p>
</td>
<td valign="top" align="right">
<p>p. 159</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>+=, -=</tt>,</p>
</td>
<td valign="top" align="left">&nbsp;</td>
<td valign="top" align="left">&nbsp;</td>
<td valign="top" align="right">
<p>p. 159</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>&lt;&lt;=, &gt;&gt;=</tt>,</p>
</td>
<td valign="top" align="left">&nbsp;</td>
<td valign="top" align="left">&nbsp;</td>
<td valign="top" align="right">
<p>p. 159</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>&amp;=</tt>,|=<tt>, ^=</tt></p>
</td>
<td valign="top" align="left">&nbsp;</td>
<td valign="top" align="left">&nbsp;</td>
<td valign="top" align="right">
<p>p. 159</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>R</p>
</td>
<td valign="top" align="left">
<p><tt>throw</tt></p>
</td>
<td valign="top" align="left">
<p>throw exception（抛出异常）</p>
</td>
<td valign="top" align="left">
<p>throw expr</p>
</td>
<td valign="top" align="right">
<p>p. 216</p>
</td>
</tr>
<tr>
<td valign="top" align="middle">
<p>L</p>
</td>
<td valign="top" align="left">
<p><tt>,</tt></p>
</td>
<td valign="top" align="left">
<p>comma（逗号）</p>
</td>
<td valign="top" align="left">
<p>expr <tt>,</tt> expr</p>
</td>
<td valign="top" align="right">
<p>p. 168</p>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>5.10.3 求值顺序</p>
<p>复合表达式的处理指导原则：(1) 如果有怀疑，则在表达式上按程序逻辑要求使用圆括号强制操作数的组合。(2)如果要修改操作数的值，则不要在同一语句的其他地方使用该操作数。如果必须使用改变的值，则把该表达式分割成两个独立的语句：在一个语句中改变该操作数的值，再在下一个语句中使用它。(3)一个表达式里，不要在两个或更多的子表达式中对同一对象做自增或自减操作。</p>
<p>5.11 new和delete表达式</p>
<p>1. 动态创建对象的初始化</p>
<p>动态创建的对象可用初始化变量的方式实现初始化：</p>
<pre class="prettyprint">int *pi = new int(1024); //object to which pi points is 1024
string *ps = new string(10, '9'); //*ps is "9999999999"</pre>
<p>2. 动态创建对象的默认初始化</p>
<p>如果不提供显式初始化，动态创建的对象与在函数内定义的变量初始化方式相同，对于类类型的对象，用该类的默认构造函数初始化；而内置类型的对象则无初始化。对于提供了默认构造函数的类类型，没有必要对其对象进行值初始化（会自动调用)。而对于内置类型或没有定义默认构造函数的类型，采用不同初始化方式则有显著的差别：</p>
<pre class="prettyprint">int *pi = new int; //pi points to an uninitialized int
int *pi = new int(); //pi points to an int value-initialized to 0</pre>
<p>&nbsp;</p>
<p>3. 耗尽内存</p>
<p>如果new表达式无法获取需要的内存空间，系统将抛出名为bad_alloc的异常。</p>
<p>4. 撤销动态创建的对象</p>
<pre class="prettyprint">delete 指针</pre>
<p>5. 零值指针的删除</p>
<p>安全。</p>
<p>6. 在delete之后，重设指针的值</p>
<p>一旦删除了指针所指向的对象，立即将指针置为0，这样就非常清楚地表明指针不再指向任何对象。</p>
<p>7. const对象的动态分配和回收</p>
<p>动态创建const对象：</p>
<pre class="prettyprint">const int *pci = new const int(1024);
</pre>
<p>动态创建的const对象必须在创建时初始化，并且一经初始化，其值就不能修改。对于类类型的const动态对象，如果该类提供了默认的构造函数，则此对象可隐式初始化。内置类型或未提供默认构造函数的类类型对象必须显式初始化。</p>
<p>8. 删除const对象</p>
<p>与普通对象的释放方式一样。</p>
<p>5.12 类型转换</p>
<p>C++定义了算术类型之间的内置转换尽可能防止精度损失。</p>
<p>5.12.1 何时发生隐式类型转换</p>
<p>在混合类型的表达式中，其操作数被转换为相同的类型；用作条件的表达式被转换为bool类型；用一表达式初始化某个变量，或一表达式赋值给某个变量，则该表达式被转换为该变量的类型。</p>
<p>5.12.2 算术转换</p>
<p>整型提升：所有比int小的整型，包括char、signed char、unsigned char、short和unsigned short，如果该类型的所有可能的值都能包容在int内，它们就会被提升为int型，否则将被提升为unsigned int。</p>
<p>1. 有符号和无符号类型之间的转换</p>
<p>包含short和int类型的表达式，short-&gt;int；如果int能容纳unsigned short，则unsigned short-&gt;int，否则unsigned short，int-&gt;unsigned int。同理，unsigned int-&gt;long，否则unsigned int，long－&gt;unsigned long。</p>
<p>对于包含signed和unsigned int型的表达式，其转换有副作用，尽量不要使用。</p>
<p>2. 理解算术转换</p>
<p>5.12.3&nbsp; 其他隐式转换</p>
<p>1. 指针转换</p>
<p>数组：</p>
<pre class="prettyprint">int ia[10];
int *ip = ia;</pre>
<p>不将数组转换为指针的情况有：数组用作取地址(&amp;)操作符的操作数或sizeof操作符的操作数时，或用数组对数组的引用进行初始化时。</p>
<p>2. 转换为bool类型</p>
<p>0、null或空字符转换为false。</p>
<p>3. 算术类型与bool类型的转换</p>
<p>将bool对象转换为算术类型时，true变成1，而false则为0。</p>
<p>4. 转换与枚举类型</p>
<p>C++自动将枚举转换为整型。</p>
<p>5. 转换为const对象</p>
<p>当使用非const对象初始化const对象的引用时，系统将非const对象转换为const对象，还可以将非const对象的地址（或非const指针）转换为指向相关const类型的指针：</p>
<pre class="prettyprint">int i;
const int cj = 0;
const int &amp;j = i;
const int *p = &amp;ci;</pre>
<p>&nbsp;</p>
<p>6. 由标准库类型定义的转换</p>
<p>5.12.4 显式转换</p>
<p>static_cast，dynamic_cast，const_cast，reinterpret_cast。</p>
<p>5.12.5 何时需要强制类型转换</p>
<p>用于强制覆盖通常的标准转换。</p>
<p>5.12.6 命名的强制类型转换</p>
<pre class="prettyprint">cast-name&lt;type&gt;(expression); /* cast-name = static_cast,dynamic_cast,
                                                const_cast,reinterpret_cast */</pre>
<p>&nbsp;</p>
<p>1. dynamic_cast</p>
<p>2. const_cast</p>
<p>将转换掉表达式的const性质。</p>
<p>3. static_cast</p>
<p>编译器隐式执行的任何类型转换都可以由static_cast显式完成。</p>
<p>4. reinterpret_cast</p>
<p>通常为操作数的位模式提供较低层次的重新解释。</p>
<pre class="prettyprint">int *ip;
char *pc = reinterpret_cast&lt;char*&gt;(ip);</pre>
<p>&nbsp;</p>
<p><font color="#ff0000">尽量避免使用强制类型转换。</font></p>
<p>5.12.7 旧式强制类型转换</p>
<pre class="prettyprint">type (expr);
(type) expr;</pre>
]]></content:encoded>
			<wfw:commentRss>http://klniu.com/post/c-primer-knowledge-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>c++ primer知识点－第4章 数组和指针</title>
		<link>http://klniu.com/post/c-primer-knowledge-4/</link>
		<comments>http://klniu.com/post/c-primer-knowledge-4/#comments</comments>
		<pubDate>Sat, 20 Dec 2008 07:35:17 +0000</pubDate>
		<dc:creator>勿慢牛</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[c++ primer]]></category>

		<guid isPermaLink="false">http://livesdrop.com/2008/12/httplivesdropcom200812c-primer-knowledge-4/</guid>
		<description><![CDATA[目录 4.1 数组 4.2 指针的引入 4.3 C风格字符串 4.4 多维数组 &#160; &#160; 4.1 数组 　　数组是由类型名、标识符和维数组成的复合数据类型。类型名可以是内置类型或类类型，也可以是除引用外的任意复合类型。 4.1.1 数组的定义和初始化 　　维数必须用值大于等于1的常量表达式定义；表达式包含整型字面值、枚举常量或者用常量表达式初始化的整型const对象。非const变量以及要到运行阶段才知道其值的const变量都不能用于定义数组的维数。 1. 显示初始化数组元素 　　未显式初始化的函数体外定义的内置数组，其元素初始化为0；未显式初始化的函数体内定义的内置数组，则无初始化。 int ia[] = {0, 1, 2}; // an array of dimension 3 2. 特殊的字符数组 char ca1[] = {'c', '+', '+'}; &#8230; <a href="http://klniu.com/post/c-primer-knowledge-4/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>目录</p>
<p>4.1 数组</p>
<p>4.2 指针的引入</p>
<p>4.3 C风格字符串</p>
<p>4.4 多维数组</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>4.1 数组</p>
<p>　　数组是由类型名、标识符和维数组成的复合数据类型。类型名可以是内置类型或类类型，也可以是除引用外的任意复合类型。</p>
<p>4.1.1 数组的定义和初始化</p>
<p>　　维数必须用值大于等于1的常量表达式定义；表达式包含整型字面值、枚举常量或者用常量表达式初始化的整型const对象。非const变量以及要到运行阶段才知道其值的const变量都不能用于定义数组的维数。</p>
<p>1. 显示初始化数组元素</p>
<p>　　未显式初始化的函数体外定义的内置数组，其元素初始化为0；未显式初始化的函数体内定义的内置数组，则无初始化。</p>
<pre><span style="color: rgb(0, 0, 255);">int</span> ia[] = {0, 1, 2}; <span style="color: rgb(0, 128, 0);">// an array of dimension 3</span></pre>
<p>2. 特殊的字符数组</p>
<pre><span style="color: rgb(0, 0, 255);">char</span> ca1[] = {'c', '+', '+'};  <span style="color: rgb(0, 128, 0);">//no null</span>
<span style="color: rgb(0, 0, 255);">char</span> ca2[] = {'c', '+', '+', '�'};  <span style="color: rgb(0, 128, 0);">//explit null</span>
<span style="color: rgb(0, 0, 255);">char</span> ca3[] = &quot;<span style="color: rgb(139, 0, 0);">c++</span>&quot;;  <span style="color: rgb(0, 128, 0);">// null terminator added automatically</span></pre>
<p>3. 不允许数值直接复制和赋值</p>
<p>　　数组不能互相复制及初始化。</p>
<p>4.1.2 数组操作</p>
<p>　　数组下标类型：size_t&nbsp;&nbsp; 。</p>
<p>4.2 指针的引入</p>
<p>4.2.1 什么是指针？</p>
<p>　　指针保存的是一个对象的地址；当&amp;取地址操作符作用于一个对象时，返回的是该对象的存储地址。</p>
<p>4.2.2 指针的定义和初始化</p>
<p>　　每个指针都有一个与之关联的数据类型，该类型决定了指针所指向的对象的类型。</p>
<p>1. 指针变量的定义</p>
<p>　　*符号把一个标识符声明为指针。</p>
<p>2. 另一种声明指针的风格</p>
<p>　　可用空格符称号*与其后的标识符分隔开来。</p>
<p>3. 续声明多个指针易导致混淆</p>
<pre><span style="color: rgb(0, 0, 255);">string</span>* ps1;  <span style="color: rgb(0, 0, 255);">string</span>* ps2;    <span style="color: rgb(0, 128, 0);">// ---------&gt;</span>
<span style="color: rgb(0, 0, 255);">string</span> *ps1, *ps2;</pre>
<p>4. 指针可能的取值</p>
<p>5. 避免使用未初始化的指针</p>
<p>&nbsp; 如果可能的话，除非所指向的对象已经存在，否则不要先定义指针，这样可避免定义一个未初始化的指针。</p>
<p>6. 指针初始化和赋值操作的约束</p>
<p>　　对指针进行初始化只能使用以下四种类型的值：</p>
<p>　　a.0值常量表达式</p>
<p>　　b.类型匹配的对象的地址</p>
<p>　　c.另一个对象之后的下一个地址</p>
<p>　　d.同类型的另一个有效地址</p>
<p>　　除了使用数值0或在编译时值为0的const量外，还可以使用C++语言从C语言中继承下来的预处理器变量NULL，定义于cstdlib。</p>
<p>7. void * 指针</p>
<p>　　void * 指针可以保存任何类型对象的地址；但仅支持几种操作：与另一指针比较；向函数传递void * 指针或从函数返回void * 指针；给另一个void * 指针赋值。</p>
<p>4.2.3 指针操作</p>
<p>　　*解引用操作符</p>
<p>1. 生成左值的解引用操作</p>
<pre>
*sp = &quot;<span style="color: rgb(139, 0, 0);">goodbye</span>&quot;; <span style="color: rgb(0, 128, 0);">//contents of s now changed</span></pre>
<p>2. 指针和引用的比较</p>
<p>　　引用总是指向某个对象；定义引用时没初始化是错误的，给引用赋值修改的是该引用所关联的对象的值。</p>
<p>3. 指向指针的指针</p>
<pre><span style="color: rgb(0, 0, 255);">int</span> ival = 1024;
<span style="color: rgb(0, 0, 255);">int</span> *pi = &amp;ival; <span style="color: rgb(0, 128, 0);">// pi points to an int</span>
<span style="color: rgb(0, 0, 255);">int</span> **ppi = &amp;pi; <span style="color: rgb(0, 128, 0);">//ppi points to a pointer to int</span></pre>
<p>4.2.4 使用指针访问数组元素</p>
<p>1. 指针的算术操作</p>
<p>　　指针相减结果类型为ptrdiff_t(有正负，signed)</p>
<p>2. 解引用和指针算术操作之间的相互作用</p>
<pre><span style="color: rgb(0, 0, 255);">int</span> last = *(ia+4);</pre>
<p>3. 下标和指针</p>
<pre><span style="color: rgb(0, 0, 255);">int</span> *p = iva[0];
<span style="color: rgb(0, 0, 255);">int</span> i = p[1]; <span style="color: rgb(0, 128, 0);">//ok</span>

<span style="color: rgb(0, 0, 255);">int</span> *p = iva[2];
<span style="color: rgb(0, 0, 255);">int</span> i = p[-2]; <span style="color: rgb(0, 128, 0);">//which equal iva[0]</span></pre>
<p>4. 计算数组的超出末端指针</p>
<pre><span style="color: rgb(0, 0, 255);">int</span>  arr[5] = [0];
<span style="color: rgb(0, 0, 255);">int</span> *p = arr; <span style="color: rgb(0, 128, 0);">//arr[0]</span>
<span style="color: rgb(0, 0, 255);">int</span> *q = p + 5; <span style="color: rgb(0, 128, 0);">//q is a ender</span></pre>
<p>不能对q进行解引用，一般只能用于比较。</p>
<p>5. 输出数组元素</p>
<p>6. 指针是数组的迭代器</p>
<p>4.2.5 指针和const限定符</p>
<p>1. 指向const对象的指针</p>
<p>　　指向const对象的指针也必须具有const特性；指向非const对象的const指针不能通过指针修改对象，但可以通过其他方法修改。</p>
<p>2. const指针</p>
<p>指向(int)型对象的const指针：</p>
<pre><span style="color: rgb(0, 0, 255);">int</span> * <span style="color: rgb(0, 0, 255);">const</span> p1;</pre>
<p>指向const对象的指针：</p>
<pre><span style="color: rgb(0, 0, 255);">const</span> <span style="color: rgb(0, 0, 255);">int</span> *p2;</pre>
<p>p1不能指向别的对象，但其指向的值能否修改取决于其类型。</p>
<p>3. 指向const对象的const指针</p>
<pre><span style="color: rgb(0, 0, 255);">const</span> <span style="color: rgb(0, 0, 255);">double</span> * <span style="color: rgb(0, 0, 255);">const</span> pi_ptr;</pre>
<p>不能指向另一个对象，且不能通过指针修改其指向的值。</p>
<p>4. 指针和typedef</p>
<pre><span style="color: rgb(0, 0, 255);">typedef</span> <span style="color: rgb(0, 0, 255);">string</span> *pstring;
<span style="color: rgb(0, 0, 255);">const</span> pstring cstr;  <span style="color: rgb(0, 128, 0);">//----------&gt;</span>
<span style="color: rgb(0, 0, 255);">string</span> * <span style="color: rgb(0, 0, 255);">const</span> cstr;</pre>
<p>4.3 C风格字符串</p>
<p>　　C风格字符串是以空字符NULL结束的字符数组。</p>
<p>1. C风格字符串的使用</p>
<p>　　利用空字符作为循环条件。</p>
<p>2. C风格字符串的标准库函数</p>
<pre>
#include &lt;cstring&gt;</pre>
<p>传递给这些标准库函数的指针必须具有非零值，并且指向以NULL结束的字符数组中的第一个元素。</p>
<p align="center">操纵C风格字符串的标准库函数</p>
<table width="748" cellspacing="10" cellpadding="2" border="0">
<tbody>
<tr>
<td width="182">strlen(s)</td>
<td width="534">返回s的长度，不包括结束符NULL</td>
</tr>
<tr>
<td width="182">strcmp(s1,s2)</td>
<td width="534">比较s1和s2是否相同，相同，返回0；s1&gt;s2，返回正数；s1&lt;s2，返回负数</td>
</tr>
<tr>
<td width="182">strcat(s1,s2)</td>
<td width="534">将字符串s2连接到s1后，返回s1</td>
</tr>
<tr>
<td width="182">strcpy(s1,s2)</td>
<td width="534">将s2复制给s1，返回s1</td>
</tr>
<tr>
<td width="182">strncat(s1,s2,n)</td>
<td width="534">将s2的前n个字符连接到s1后面，并返回s1</td>
</tr>
<tr>
<td width="182">strcpy(s1,s2,n)</td>
<td width="534">将s2的前n个字符复制到s1，并返回s1</td>
</tr>
</tbody>
</table>
<p>3. 永远不要忘记字符串结束符NULL</p>
<pre><span style="color: rgb(0, 0, 255);">char</span> ca[] = {'c', '+', '+'}; <span style="color: rgb(0, 128, 0);">//not null-terminated</span>
cout &lt;&lt; strlen(ca) &lt;&lt; endl; <span style="color: rgb(0, 128, 0);">// disaster:ca isn't null-terminated</span></pre>
<p>4. 调用者必须确保目标字符串具有足够大小</p>
<p>&nbsp; strcat，strcpy。</p>
<p>5. 使用strn函数处理C风格字符串</p>
<p>&nbsp; strncat，strncpy可以控制字符个数，但是不要忘了字符串结尾的&#8217;�&#8217;。</p>
<p>6. 尽可能使用标准库类型string</p>
<p>4.3.1 创建动态数组</p>
<p>1. 动态数组的定义</p>
<p>　　动态数组定义不需要为数组命名，定义后返回数组第一个元素的指针。</p>
<pre>&nbsp;</pre>
<pre><span style="color: rgb(0, 0, 255);">int</span> *pia = <span style="color: rgb(0, 0, 255);">new</span> <span style="color: rgb(0, 0, 255);">int</span>[10]; <span style="color: rgb(0, 128, 0);">//array of 10 uninitialized ints</span></pre>
<p>其中的维数可以是任意复杂的表达式。</p>
<p>2. 初始化动态分配的数组</p>
<p>　　动态数值中如果元素为类类型，则使用默认构造函数，内置类型元素无初始化；可以在动态数组长度后面加一对空圆括号，对其进行初始化，但不能初始化为不同的初值。</p>
<p>3. const对象的动态数组</p>
<p>　　必须初始化，不允许修改，因些用处不大。</p>
<p>4. 允许动态分配空数组</p>
<p>　　可以分配长度为0的动态数组，但其仅支持以下操作：比较运算（不能在循环中使用）；加减0，得0值。</p>
<p>5. 动态空间的释放</p>
<p>　　动态分配的内存必须进行释放。</p>
<pre><span style="color: rgb(0, 0, 255);">delete</span> [] pia;</pre>
<p>6. 动态数组的使用</p>
<p>常常使用char*指针指向多个C风格字符串；采用这种技术比建立固定大小的数组安全。</p>
<p>4.3.2 新旧代码的兼容</p>
<p>1. 混合使用标准库类string和C风格字符串</p>
<p>　　可以把C风格字符串用在任何可以使用字符串字面值的地方：a.可以使用C风格字符串对string对象进行初始化或赋值。b.string类型可以使用C风格字符串作为加减法操作的其中一个操作数；也允许将其用作复合赋值操作的右操作数。</p>
<p>2. 使用数组初始化vector对象</p>
<p>　　使用数组初始化vector对象，必须指出用于初始化式的第一个元素以及数组最后一个元素的下一个位置的地址：</p>
<pre><span style="color: rgb(0, 0, 255);">const</span> size_t arr_size = 6;
<span style="color: rgb(0, 0, 255);">int</span> int_arr[arr_size} = {0, 1, 2, 3, 4, 5};
vector&lt;<span style="color: rgb(0, 0, 255);">int</span>&gt; ivec(int_arr, int_arr + int_size);</pre>
<p>　　传递给ivec的两个指针标出了vector初值的范围，被标出的元素范围可以是数组的子集。</p>
<pre>
vector&lt;<span style="color: rgb(0, 0, 255);">int</span>&gt; ivec(int_arr, int_arr + 4); <span style="color: rgb(0, 128, 0);">//three elements</span></pre>
<p>4.4 多维数组</p>
<p>　　int[2][3]，第一维称为行，第二维称为列。</p>
<p>1. 多维数组的初始化</p>
<pre><span style="color: rgb(0, 0, 255);">int</span> ia[3][4] = {{0,1,2,3},{4,5,6,7},{8,9,10,11}};</pre>
<p>只初始化每行的第一个元素</p>
<pre><span style="color: rgb(0, 0, 255);">int</span> ia[3][4] = {{0},{4},{8}};</pre>
<p>2. 多维数组的下标引用</p>
<p>　　当需要访问数组中的特定元素时，必须提供其行下标和列下标。如果表达式只提供了一个下标，则结果获取的元素是该行下标索引的内层数组。</p>
<p>指针和多维数组</p>
<p>　　由多维数组转换而成的指针类型应是指向第一个内层数组的指针。</p>
<pre><span style="color: rgb(0, 0, 255);">int</span> *ip[4]; <span style="color: rgb(0, 128, 0);">//array of pointers to int</span>
<span style="color: rgb(0, 0, 255);">int</span> (*ip)[4]; <span style="color: rgb(0, 128, 0);">//pointers to an array of 4 ints</span></pre>
<p>用typedef简化指向多维数组的指针</p>
<pre><span style="color: rgb(0, 0, 255);">typedef</span> <span style="color: rgb(0, 0, 255);">int</span> int_array[4]; <span style="color: rgb(0, 128, 0);">//array of points to int</span>
int_arr *ip = ia; <span style="color: rgb(0, 128, 0);">//points to an array of 4 ints</span></pre>
]]></content:encoded>
			<wfw:commentRss>http://klniu.com/post/c-primer-knowledge-4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>c++ primer知识点-第3章 标准库类型</title>
		<link>http://klniu.com/post/c-primer-knowledge-3/</link>
		<comments>http://klniu.com/post/c-primer-knowledge-3/#comments</comments>
		<pubDate>Sat, 13 Dec 2008 11:52:51 +0000</pubDate>
		<dc:creator>勿慢牛</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[c++ primer]]></category>

		<guid isPermaLink="false">http://livesdrop.com/2008/12/c-primer%e7%9f%a5%e8%af%86%e7%82%b9-%e7%ac%ac3%e7%ab%a0-186/</guid>
		<description><![CDATA[第3章 标准库类型 目录 3.1 命名空间的using声明 3.2 标准库string类型 3.3 标准库vector类型 3.4 迭代器简介 3.5标准库bitset类型 &#160; 3.1 命名空间的using声明 1.每个名字都需要一个using声明 必须要为用到的每个名字都提供一个using声明。 2.使用标准库类型的类定义 在头文件中放置using声明，就相当于在包含该头文件的每个程序中都放置了同一using声明。 3.2 标准库string类型 string类型支持长度可变的字符中；使用前请首先 #include &#60;string&#62; using std::string; 3.2.1 string对象的定义和初始化 　　几种初始化String对象的方式 string s1; 默认构造函数，s1为空串 string s2(s1); 将s2初始化为s1的一个副本 string s3(&#34;value&#34;); 将s3初始化为一个字符串字面值副本 string s4(n,&#8217;c'); &#8230; <a href="http://klniu.com/post/c-primer-knowledge-3/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>第3章 标准库类型</p>
<p>目录</p>
<p>3.1 命名空间的using声明</p>
<p>3.2 标准库string类型</p>
<p>3.3 标准库vector类型</p>
<p>3.4 迭代器简介</p>
<p>3.5标准库bitset类型</p>
<p>&nbsp;</p>
<p>3.1 命名空间的using声明</p>
<p>1.每个名字都需要一个using声明</p>
<p>必须要为用到的每个名字都提供一个using声明。</p>
<p>2.使用标准库类型的类定义</p>
<p>在头文件中放置using声明，就相当于在包含该头文件的每个程序中都放置了同一using声明。</p>
<p>3.2 标准库string类型</p>
<p>string类型支持长度可变的字符中；使用前请首先</p>
<pre>
#include &lt;<span style="color: rgb(0, 0, 255);">string</span>&gt;
<span style="color: rgb(0, 0, 255);">using</span> std::<span style="color: rgb(0, 0, 255);">string</span>;</pre>
<p>3.2.1 string对象的定义和初始化</p>
<p style="text-align: left;">　　几种初始化String对象的方式</p>
<table cellspacing="1" cellpadding="1" border="0" align="center" style="width: 565px; height: 176px;">
<tbody>
<tr>
<td>string s1;</td>
<td>默认构造函数，s1为空串</td>
</tr>
<tr>
<td>string s2(s1);</td>
<td>将s2初始化为s1的一个副本</td>
</tr>
<tr>
<td>string s3(&quot;value&quot;);</td>
<td>将s3初始化为一个字符串字面值副本</td>
</tr>
<tr>
<td>string s4(n,&#8217;c');</td>
<td>将s4初始化为字符&#8217;c'的n个副本</td>
</tr>
</tbody>
</table>
<p>3.2.2 String对象的读写</p>
<p>　　string类型的输入操作符：</p>
<p>读取并忽略开头所有的空白字符（如空格，换行符，制表符）。</p>
<p>读取字符直至再次遇到空白字符，读取终止。</p>
<p>允许把多个读操作或多个写操作放在一起。</p>
<p>1.读入未知数目的string对象</p>
<p>　　string的输入操作符也会返回所读的数据流。因此，可以把输入操作作为判断条件。</p>
<p>2.用getline读取整行文本</p>
<pre>
getline(stream-in,<span style="color: rgb(0, 0, 255);">string</span>);</pre>
<p>　　getline 并不忽略行开头的换行符。只要GETLINE遇到换行符，即便它是输入的第一个字符，getline也将停止读入并返回。如果第一个字符就是换行符，则string参数将被置为空string。getline函数将istream参数作为返回值，和输入操作符一样也把它用作判断条件。</p>
<p>3.2.3 string对象的操作</p>
<p>string操作</p>
<table width="628" cellspacing="8" cellpadding="2" border="0">
<tbody>
<tr>
<td width="199" valign="top">s.empty()</td>
<td width="403" valign="top">判断s是否为空串，是返回true，否则返回false</td>
</tr>
<tr>
<td width="200" valign="top">s.size()</td>
<td width="402" valign="top">返回s中字符的个数</td>
</tr>
<tr>
<td width="201" valign="top">s[n]</td>
<td width="402" valign="top">返回s中位置为n的字符，位置从0开始计数</td>
</tr>
<tr>
<td width="201" valign="top">s1+s2</td>
<td width="402" valign="top">把s1和s2连接成一个新的字符串，返回新生成的字符串</td>
</tr>
<tr>
<td width="201" valign="top">s1=s2</td>
<td width="402" valign="top">把s1内容替换为s2副本</td>
</tr>
<tr>
<td width="201" valign="top">v1==v2</td>
<td width="402" valign="top">比较v1和v2，相等则返回true，否则返回false</td>
</tr>
<tr>
<td width="201" valign="top">!，=,&lt;,&lt;=,&gt;,&gt;=</td>
<td width="402" valign="top">保持这些操作符惯有的含义</td>
</tr>
</tbody>
</table>
<p>1.string的size和empty操作</p>
<p>string对象的长度指的是string对象中字符的个数，可以通过size操作获取，了解string对象是否为空：</p>
<pre><span style="color: rgb(0, 0, 255);">if</span> (st.size() == 0)     <span style="color: rgb(0, 128, 0);">// ok: empty</span>
<span style="color: rgb(0, 0, 255);">if</span> (st.empty())        <span style="color: rgb(0, 128, 0);">// ok: empty</span></pre>
<p>2.string::size_type类型</p>
<p>　　size成员函数返回的是string::size_type类型的值，该库类型隐藏了与机器相关的取值类型。size_type与unsigned型具有相同的含义。</p>
<p>　　任何存储string的size操作结果的变量必须为string::size_type类型。特别重要的是，不要把size的返回值赋给一个int变量。</p>
<p>3.string关系操作符</p>
<p>　　string对象比较运算是区分大小写的，任何一个大写字母都小于任意的小写字母。如果两个string对象长度不同，且短的string对象与长的string对象的前面部分相匹配，则短的string对象小于长的string对象。 如果两个string对象的字符不同，则比较第一个不匹配的字符。</p>
<p>4.string对象的赋值</p>
<p>　　可以把一个string对象赋值到另一个string对象。</p>
<p>5.两个string对象相加</p>
<p>　　string对象的加法被定义为连接。也就是说，两个（或多个）string对象可以通过使用加操作符+或者复合赋值操作符+=连接起来。</p>
<p>6.和字符串字面值的连接</p>
<p>　　当进行string对象和字符串字面值混合连接操作时，+操作符的左右操作数必须至少有一个是string类型的：</p>
<pre><span style="color: rgb(0, 0, 255);">string</span> s1 = &quot;<span style="color: rgb(139, 0, 0);">hello</span>&quot;;   <span style="color: rgb(0, 128, 0);">// no punctuation</span>
<span style="color: rgb(0, 0, 255);">string</span> s2 = &quot;<span style="color: rgb(139, 0, 0);">world</span>&quot;;
<span style="color: rgb(0, 0, 255);">string</span> s3 = s1 + &quot;<span style="color: rgb(139, 0, 0);">, </span>&quot;;                <span style="color: rgb(0, 128, 0);">// ok: adding a string and a literal</span>
<span style="color: rgb(0, 0, 255);">string</span> s4 = &quot;<span style="color: rgb(139, 0, 0);">hello</span>&quot; + &quot;<span style="color: rgb(139, 0, 0);">, </span>&quot;;              <span style="color: rgb(0, 128, 0);">// error: no string operand</span>
<span style="color: rgb(0, 0, 255);">string</span> s5 = s1 + &quot;<span style="color: rgb(139, 0, 0);">, </span>&quot; + &quot;<span style="color: rgb(139, 0, 0);">world</span>&quot;;        <span style="color: rgb(0, 128, 0);">// ok: each + has string operand</span>
<span style="color: rgb(0, 0, 255);">string</span> s6 = &quot;<span style="color: rgb(139, 0, 0);">hello</span>&quot; + &quot;<span style="color: rgb(139, 0, 0);">, </span>&quot; + s2;        <span style="color: rgb(0, 128, 0);">// error: can't add string literals</span></pre>
<p>7.从string对象获取字符</p>
<p>　　string类型通过下标操作符([])来访问string对象中的单个字符。下标操作符需要取一个size_type类型的值。</p>
<p>8.下标操作可用作左值(可以被赋值)</p>
<p>9.计算下标值</p>
<p>　　任何可产生整型数值的表达式都可用作下标操作符的索引。在使用下标索引string对象时，必须保证索引值&ldquo;在上下界范围内&rdquo;。</p>
<p>3.2.4 string对象中字符的处理</p>
<p>cctype头文件中定义:</p>
<table width="672" cellspacing="10" cellpadding="2" border="0">
<tbody>
<tr>
<td width="205">isalnum(c)</td>
<td width="435">如果c是字母或数字，则为true。</td>
</tr>
<tr>
<td width="206">isalpha(c)</td>
<td width="435">如果c是字母，则为true。</td>
</tr>
<tr>
<td width="206">iscntrl(c)</td>
<td width="435">如果c是控制字符，则为true。</td>
</tr>
<tr>
<td width="206">isdigit(c)</td>
<td width="435">如果c是数字，则为true。</td>
</tr>
<tr>
<td width="206">isgraph(c)</td>
<td width="435">如果c不是空格，但可输出，则为true。</td>
</tr>
<tr>
<td width="206">islower(c)</td>
<td width="435">如果c是小写字母，则为true。</td>
</tr>
<tr>
<td width="206">isprint(c)</td>
<td width="435">如果c是可输出的字符，则为true。</td>
</tr>
<tr>
<td width="206">ispunct(c)</td>
<td width="435">如果c是标点符号，则为true。</td>
</tr>
<tr>
<td width="206">isspace(c)</td>
<td width="435">如果c是空白字符，则为true。</td>
</tr>
<tr>
<td width="206">isupper(c)</td>
<td width="435">如果c是大写字母，则为true。</td>
</tr>
<tr>
<td width="206">isxdigit(c)</td>
<td width="435">如果c是十六进制数，则为true。</td>
</tr>
<tr>
<td width="206">tolower(c)</td>
<td width="435">如果c是大写字母，则返回其小写字母形式，否则直接返回c。</td>
</tr>
<tr>
<td width="206">toupper(c)</td>
<td width="435">如果c是小写字母，则返回其大写字母形式，否则直接返回c。</td>
</tr>
</tbody>
</table>
<p>　　可打印的字符是指那些可以显式表示的字符。空白字符则是空格、制表符、垂直制表符、回车符、换行符和进纸符中的任意一种；标点符号则是除了数字、字母或（可输出的）空白字符（如空格）以外的其他字符。</p>
<p>3.3 标准库vector类型</p>
<p>　　vector称为容器，是一个类模板。vector声明：</p>
<pre>
vector&lt;<span style="color: rgb(0, 0, 255);">int</span>&gt; ivec;                 <span style="color: rgb(0, 128, 0);">// ivec holds objects of type int</span>
vector&lt;Sales_item&gt; Sales_vec;    <span style="color: rgb(0, 128, 0);">// holds Sales_items</span></pre>
<p>3.3.1 vector对象的定义和初始化</p>
<p>vector类构造函数</p>
<table width="581" cellspacing="10" cellpadding="2" border="0">
<tbody>
<tr>
<td width="200" valign="top">vector&lt;T&gt; v1;</td>
<td width="349" valign="top">vector保存类型为T的对象。默认构造函数为空</td>
</tr>
<tr>
<td width="200" valign="top">vector&lt;T&gt; v2(v1);</td>
<td width="349" valign="top">v2是v1的一个副本</td>
</tr>
<tr>
<td width="200" valign="top">vector&lt;T&gt; v3(n,i);</td>
<td width="349" valign="top">v3包含n个值为i的元素</td>
</tr>
<tr>
<td width="200" valign="top">vector&lt;T&gt; v4(n);</td>
<td width="349" valign="top">v4含有值初始化的元素的n个副本</td>
</tr>
</tbody>
</table>
<p>1.创建确定个数的元素</p>
<p>　　当把一个vector对象复制到另一个vector对象时，新复制的vector中每一个元素都初始化为原vector中相应元素的副本。但这两个vector对象必须保存同一种元素类型。构造函数用元素个数来决定vector对象保存元素的个数，元素值指定每个元素的初始值。</p>
<p>　　vector对象动态增长(高效)。</p>
<p>2.值初始化</p>
<p>　　如果vector保存内置类型（如int类型）的元素，那么标准库将用0值创建元素初始化值，如果向量保存类类型（如string）的元素，标准库将用该类型的默认构造函数创建元素初始值。</p>
<p>3.3.2 vector的操作</p>
<table width="535" cellspacing="10" cellpadding="2" border="0">
<tbody>
<tr>
<td width="200" valign="top">v.empty()</td>
<td width="303" valign="top">如果v为空，则返回true，否则返回false</td>
</tr>
<tr>
<td width="200" valign="top">v.size()</td>
<td width="303" valign="top">返回v中元素的个数</td>
</tr>
<tr>
<td width="200" valign="top">v.pushback(t)</td>
<td width="303" valign="top">在v的末尾增加一个值为t的元素</td>
</tr>
<tr>
<td width="200" valign="top">v[n]</td>
<td width="303" valign="top">返回v中位置为n的元素</td>
</tr>
<tr>
<td width="200" valign="top">v1==v2</td>
<td width="303" valign="top">如果v1和v2相等，则返回true</td>
</tr>
<tr>
<td width="200" valign="top">v1=v2</td>
<td width="303" valign="top">把v1的元素替换为v2中元素的副本</td>
</tr>
<tr>
<td width="200" valign="top">!,&lt;,&lt;=,&gt;,&gt;=</td>
<td width="303" valign="top">保持惯有含义</td>
</tr>
</tbody>
</table>
<p>1.vector对象的size</p>
<p>　　成员函数size返回相应vector类定义的size_type的值。使用size_type类型时，必须指出该类型是在哪里定义的:</p>
<pre>
vector&lt;<span style="color: rgb(0, 0, 255);">int</span>&gt;::size_type</pre>
<p>2.向vector添加元素</p>
<p>　　push_back()操作接受一个元素值，并将它作为一个新的元素添加到vector对象的后面。</p>
<p>3.vector的下标操作</p>
<p>4.下标操作不添加元素</p>
<p>　　必须是已存在的元素才能用下标操作符进行索引。通过下标操作进行赋值时，不会添加任何元素。</p>
<p><font color="#ff0000">警告：仅能对确知已存在的元素进行下标操作。</font></p>
<p>3.4 迭代器简介</p>
<p>　　迭代器是一种检查容器内元素并遍历元素的数据类型。</p>
<p>1.容器的iterator类型</p>
<pre>
vector&lt;<span style="color: rgb(0, 0, 255);">int</span>&gt;::iterator iter;</pre>
<p>这条语句定义了一个名为iter的变量，它的数据类型是由vector&lt;int&gt;定义的iterator类型。</p>
<p>2.begin和end操作</p>
<pre>
vector&lt;<span style="color: rgb(0, 0, 255);">int</span>&gt;::iterator iter = ivec.begin();</pre>
<p>返回迭代器指向的第一个元素。</p>
<p>　　由end操作返回的迭代器指向vector的&ldquo;末端元素的下一个&rdquo;。通常称为超出末端迭代器，表明它指向了一个不存在的元素。</p>
<p>3.vector迭代器的自增和解引用运算</p>
<p>　　迭代器类型可使用解引用操作符（*操作符）来访问迭代器所指向的元素，迭代器使用自增操作符向前移动迭代器指向容器中下一个元素。</p>
<p>4.迭代器的其他运算</p>
<p>5.迭代器应用的程序示例</p>
<p>6.const_iterator</p>
<p>　　对const_interator类型解引用时，得到一个指向const对象的引用，该对象不能重写。</p>
<p>7.迭代器的算术操作</p>
<p>　　包括：iter+n，iter-n，产生一个位置在iter所指元素之前（加）或之后（减）n个元素的位置。加或减之后的结果必须指向iter所指vector中的某个元素，加上或减去的值的类型应该是vector的size_type或different_type类型。iter1-iter2，产生两迭代器之间的距离；类型为different_type，它是signed类型。</p>
<p><font color="#ff0000">注意：任何改变vector长度的操作都会使迭代器失效。</font></p>
<p>3.5 标准库bitset类型</p>
<pre>
#include &lt;bitset&gt;
<span style="color: rgb(0, 0, 255);">using</span> std::bitset;</pre>
<p>3.5.1 bitset的定义和初始化</p>
<p>　　在定义bitset时，要明确bitset含有多少位，须在尖括号内给出它的长度值：</p>
<pre>
bitset&lt;32&gt; bitvec; <span style="color: rgb(0, 128, 0);">//32位，全为0。</span></pre>
<p>　　长度值必须定义为整型字面值常量或是已用常量值初始化的整数类型的const对象。</p>
<p>初始化bitset对象的方法</p>
<table width="507" cellspacing="10" cellpadding="2" border="0">
<tbody>
<tr>
<td width="200" valign="top">bitset&lt;n&gt; b;</td>
<td width="275" valign="top">b为n位，每位都为0</td>
</tr>
<tr>
<td width="200" valign="top">bitset&lt;n&gt; b(u);</td>
<td width="275" valign="top">b是unsigned long型u的一个副本</td>
</tr>
<tr>
<td width="200" valign="top">bitset&lt;n&gt; b(s);</td>
<td width="275" valign="top">b是string对象s中含有的位串的副本</td>
</tr>
<tr>
<td width="200" valign="top">bitset&lt;n&gt; b(s,pos,n);</td>
<td width="275" valign="top">b是s中从位置pos开始的n个位的副本</td>
</tr>
</tbody>
</table>
<p>1.用unsigned值初始化bitset对象</p>
<p>　　当用unsigned long值作为bitset对象的初始值时，该值将转化为二进制的位模式。如果bitset类型长度大于unsigned long值的二进制位数，则其余的高阶位置为0；如果bitet类型长度小于unsigned long值的二进制位数，则只使用unsigned值中的低阶位，超过bitet类型长度的高阶位将被丢弃。</p>
<pre><span style="color: rgb(0, 128, 0);">// bitvec1 is smaller than the initializer</span>

bitset&lt;16&gt; bitvec1(0xffff);          <span style="color: rgb(0, 128, 0);">// bits 0 ... 15 are set to 1</span>

<span style="color: rgb(0, 128, 0);">// bitvec2 same size as initializer</span>

bitset&lt;32&gt; bitvec2(0xffff);          <span style="color: rgb(0, 128, 0);">// bits 0 ... 15 are set to 1; 16 ... 31 are 0</span>

<span style="color: rgb(0, 128, 0);">// on a 32-bit machine, bits 0 to 31 initialized from 0xffff</span>

bitset&lt;128&gt; bitvec3(0xffff);         <span style="color: rgb(0, 128, 0);">// bits 32 through 127 initialized to zero</span></pre>
<p>2.用string对象初始化bitset对象</p>
<p>　　从string对象读入位集的顺序是从右向左：</p>
<pre><span style="color: rgb(0, 0, 255);">string</span> strval(&quot;<span style="color: rgb(139, 0, 0);">1100</span>&quot;);

bitset&lt;32&gt; bitvec4(strval);</pre>
<p>bitvec4的位模式中第2和3的位置为1，其余位置都为0。</p>
<p>可以只用某个子串作为初始值：</p>
<pre><span style="color: rgb(0, 0, 255);">string</span> str(&quot;<span style="color: rgb(139, 0, 0);">1111111000000011001101</span>&quot;);

bitset&lt;32&gt; bitvec5(str, 5, 4); <span style="color: rgb(0, 128, 0);">// 4 bits starting at str[5], 1100</span>

bitset&lt;32&gt; bitvec6(str, str.size() - 4);     <span style="color: rgb(0, 128, 0);">// use last 4 characters</span></pre>
<p>3.5.2 bitset对象上的操作</p>
<table width="579" cellspacing="10" cellpadding="2" border="0">
<tbody>
<tr>
<td width="202">b.any()</td>
<td width="345">b中是否存在置为1的二进制位？</td>
</tr>
<tr>
<td width="202">b.none()</td>
<td width="345">b中不存在置为1的二进制位吗？</td>
</tr>
<tr>
<td width="202">b.count()</td>
<td width="345">b中置为1的二进制位的个数</td>
</tr>
<tr>
<td width="202">b.size()</td>
<td width="345">b中二进制位的个数</td>
</tr>
<tr>
<td width="202">b[pos]</td>
<td width="345">访问b中在pos处的二进制位</td>
</tr>
<tr>
<td width="202">
<p>b.test(pos)</p>
</td>
<td width="345">b中在pos处的二进制位是否为1？</td>
</tr>
<tr>
<td width="202">
<p>b.set()</p>
</td>
<td width="345">把b中所有二进制位都置为1</td>
</tr>
<tr>
<td width="202">
<p>b.set(pos)</p>
</td>
<td width="345">把b中在pos处的二进制位置为1</td>
</tr>
<tr>
<td width="202">b.reset()</td>
<td width="345">把b中所有二进制位都置为0</td>
</tr>
<tr>
<td width="202">
<p>b.reset(pos)</p>
</td>
<td width="345">把b中在pos处的二进制位置为0</td>
</tr>
<tr>
<td width="202">
<p>b.flip()</p>
</td>
<td width="345">把b中所有二进制位逐位取反</td>
</tr>
<tr>
<td width="202">b.flip(pos)</td>
<td width="345">
<p>把b中在pos处的二进制位取反</p>
</td>
</tr>
<tr>
<td width="202">
<p>b.to_ulong()</p>
</td>
<td width="345">
<p>用b中同样的二进制位返回一个unsigned long值</p>
</td>
</tr>
<tr>
<td width="202">
<p>os &lt;&lt; b</p>
</td>
<td width="345">
<p>把b中的位集输出到os流</p>
</td>
</tr>
</tbody>
</table>
<p>1.测试整个bitset对象</p>
<p>　　count操作的返回类型是标准库中命名为size_t的类型，是一个与机器无关的unsigned类型。</p>
<p>2.访问bitset对象中的位</p>
<p>3.对整个bitset对象进行设置</p>
<p>4.获取bitset对象的值</p>
<p>　　to_ulong操作返回一个unsigned long值，该值与bitset对象的位模式存储值相同。仅当bitset类型的长度小于或等于unsigned long的长度时，才可以使用to_ulong操作。</p>
<p>5.输出二进制位</p>
<p>6.使用位操作符</p>
]]></content:encoded>
			<wfw:commentRss>http://klniu.com/post/c-primer-knowledge-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>c++ primer知识点-第2章 变量和基本类型</title>
		<link>http://klniu.com/post/c-primer-knowledge-2/</link>
		<comments>http://klniu.com/post/c-primer-knowledge-2/#comments</comments>
		<pubDate>Tue, 02 Dec 2008 15:01:39 +0000</pubDate>
		<dc:creator>勿慢牛</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[c++ primer]]></category>

		<guid isPermaLink="false">http://livesdrop.com/2008/12/c-primer%e7%9f%a5%e8%af%86%e7%82%b9-%e7%ac%ac%e4%ba%8c%e7%ab%a0-154/</guid>
		<description><![CDATA[第2章 变量和基本类型 目录 2.1 基本内置类型 2.2 字面值常量 2.3 变量 2.4 const 限定符 2.5 引用 2.6 typedef 名字 2.7 枚举 2.8 类类型 2.9 编写自己的头文件 &#160; &#160; 2.1 基本内置类型 　　C++定义了一组表示整数、浮点数、单个字符和布尔值的算术类型，另外，还定义了一种称为void的特殊类型，void类型没有对应的值，仅用在有限的一些情况下，通常用作无返回值函数的返回类型。 C++算术类型 类型 含义 最小存储空间 bool 布尔型 &#8212; char 字符型 8位 wchar_t 宽字符型 &#8230; <a href="http://klniu.com/post/c-primer-knowledge-2/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>第2章 变量和基本类型</p>
<p>目录</p>
<p>2.1 基本内置类型</p>
<p>2.2 字面值常量</p>
<p>2.3 变量</p>
<p>2.4 const 限定符</p>
<p>2.5 引用</p>
<p>2.6 typedef 名字</p>
<p>2.7 枚举</p>
<p>2.8 类类型</p>
<p>2.9 编写自己的头文件</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>2.1 基本内置类型</p>
<p>　　C++定义了一组表示整数、浮点数、单个字符和布尔值的算术类型，另外，还定义了一种称为void的特殊类型，void类型没有对应的值，仅用在有限的一些情况下，通常用作无返回值函数的返回类型。</p>
<blockquote>
<p align="center">C++算术类型</p>
<table width="589" cellspacing="0" cellpadding="15" border="0">
<tbody>
<tr>
<td width="190" align="middle">类型</td>
<td width="212" align="middle">含义</td>
<td width="185" align="middle">最小存储空间</td>
</tr>
<tr>
<td width="190" align="middle">bool</td>
<td width="212" align="middle">布尔型</td>
<td width="185" align="middle">&mdash;</td>
</tr>
<tr>
<td width="190" align="middle">char</td>
<td width="212" align="middle">字符型</td>
<td width="185" align="middle">8位</td>
</tr>
<tr>
<td width="190" align="middle">wchar_t</td>
<td width="212" align="middle">宽字符型</td>
<td width="185" align="middle">16位</td>
</tr>
<tr>
<td width="190" align="middle">short</td>
<td width="212" align="middle">短整型</td>
<td width="185" align="middle">16位</td>
</tr>
<tr>
<td width="190" align="middle">int</td>
<td width="212" align="middle">整型</td>
<td width="185" align="middle">16位</td>
</tr>
<tr>
<td width="190" align="middle">long</td>
<td width="212" align="middle">长整型</td>
<td width="185" align="middle">32位</td>
</tr>
<tr>
<td width="190" align="middle">float</td>
<td width="212" align="middle">单精度浮点型</td>
<td width="185" align="middle">6位有效数字</td>
</tr>
<tr>
<td width="190" align="middle">double</td>
<td width="212" align="middle">双精度浮点型</td>
<td width="185" align="middle">10位有效数字</td>
</tr>
<tr>
<td width="190" align="middle">long double</td>
<td width="213" align="middle">扩展精度浮点型</td>
<td width="187" align="middle">10位有效数字</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
</blockquote>
<p>2.1.1 整型</p>
<p>表示整型、字符和布尔值的算术类型合称为整型。字符类型有两种：char和wchar_t。char类型保证了足够的空间，能够存储机器基本字符集中任何字符对应的数值。因此，char类型通常是单个机器字节(byte)。wchar_t类型用于扩展字符集，比如汉语和日语，这些字符集中的一些字符不能用单个char表示。</p>
<p>　　short、int和long类型都表示整型，存储空间的大小不同。一般，short类型为半个机器字长，int类型为一个机器字长，而long类型为一个或两个机器字长（在32位机器中int类型和long类型通常字长是相同的）。</p>
<p>　　bool类型表示真值true和false，可以将算术类型的任何值赋给bool对象。0值算术类型代表false，任何非0的值都代表true。</p>
<p>1. 带符号和无符号类型</p>
<p>　　整型int、short和long都默认为带符号型。要获得无符号型则必须指定该类型为unsigned。unsigned int类型可以简写为unsigned.</p>
<p>　　char有三种不同的类型：普通char，unsigned char，signed char，但只有两种表示方式，可以使用unsigned char或signed char表示char类型。使用哪种char表示方式由编译器决定。</p>
<p>2. 整型值的表示</p>
<p>　　定义一种类型使用8位表示，那么这种类型的unsigned型可以取值0到255。</p>
<p>3. 整型的赋值</p>
<p>　　当我们试着把一个超出其取值范围的值赋给一个指定的对象时，结果会怎样？答案取决于这种类型是signed还是unsigned。对于unsigned类型来说，编译器会将该值对unsigned类型的可能取值数目求模，然后取得所得值，负数也一样。对于signed类型来说，由编译器决定。在实际操作中，大部分编译器会采用与unsigned类型相同的方式。</p>
<p>2.1.2 浮点型</p>
<p>　　float单精度浮点值（32位）；double双精度浮点值（64位）；long double扩展精度浮点值（三个或四个字）。</p>
<p>　　float型只能保证6位有效数字，double至少可以保证10位有效数字。</p>
<p>2.2 字面值常量</p>
<p>　　值不能修改；只有内置类型的字面值。</p>
<p>1.整型字面值规则</p>
<p>　　支持三种进制：十进制、八进制（以0开头的字面值常量）、十六进制（以0x或0X开头的）。字面值整数常量的类型默认为int或long类型，其精度取决于字面值，通过增加后缀，能够强制将字面值整数常量转换为long，unsigned或unsigned long，通过在数值后面加L或l指定常量为long类型，可通过在数值后面加U或u定义unsigned类型。同时加L和U就能够得到unsigned long类型的字面值常量。</p>
<p>2. 浮点字面值规则</p>
<p>　　使用科学计数法时，指数用E或者e表示。默认的浮点字面值常量为double类型。在数值的后面加上F或f表示单精度。同样加上L或者l表示扩展精度（再次提醒，不提倡使用小写字母l）。</p>
<p>3. 布尔字面值和字符字面值</p>
<p>　　单词true和false是布尔型的字面值；可打印的字符型字面值通常用一对单引号来定义：</p>
<pre>
'a' '2' ',' ' ' <span style="color: rgb(0, 128, 0);">// blank</span>这些字面值都是char类型的。在字符字面值前加L就能够得到wchar_t类型的宽字符字面值。如：L<em>'</em>a<em>'。</em></pre>
<p>4. 非打印字符的转义序列</p>
<p>　　不可打印字符和特殊字符都用转义字符书写。转义字符都以反斜线符号开始：</p>
<pre>
换行符              n                       水平制表符     t</pre>
<pre>
纵向制表符          v                       退格符         b
</pre>
<pre>
回车符              r                       进纸符         f
</pre>
<pre>
报警（响铃）符      a                       反斜线
</pre>
<pre>
疑问号              ?                       单引号         &rsquo;
</pre>
<pre>
双引号              &quot;</pre>
<p>5. 字符串字面值</p>
<p>　　字符串字面值常量用双引号括起来的零个或者多个字符表示。不可打印字符表示成相应的转义字符。C++中所有的字符串字面值都由编译器自动在末尾添加一个空字符。存在宽字符串字面值，在字符串字面值前面加&ldquo;L&rdquo;，以一个宽空字符结束。</p>
<p>6. 字符串字面值的连接</p>
<p>　　两个相邻的仅由空格、制表符或换行分开的字符串字面值（或宽字符串字面值）可连接成一个新字符串字面值。如果连接字符串字面值和宽字符串字面值结果是未定义的。</p>
<p>7. 多行字面值</p>
<p>　　在一行的末尾加一反斜线符号可将此行和下一行当作同一行处理。反斜线符号必需是该行的尾字符&mdash;&mdash;不允许有注释或空格符。同样，后继行行首的任何空格和制表符都是字符串字面值的一部分。正因如此，长字符串字面值的后继行才不会有正常的缩进。</p>
<p>2.3 变量</p>
<p>2.3.1&nbsp; 什么是变量</p>
<p>　　变量提供了程序可以操作的有名字的存储区。C++中的每一个变量都有特定的类型，该类型决定了变量的内存大小和布局、能够存储于该内存中的值的取值范围以及可应用在该变量上的操作集。</p>
<p>　　左值：左值可以出现在赋值语句的左边或右边；右值：右值只能出现在赋值的右边，不能出现在赋值语句的左边。</p>
<p>2.3.2&nbsp; 变量名</p>
<p>　　变量名，即变量的标识符（identifier），可以由字母、数字和下划线组成。变量名必须以字母或下划线开头，并且区分大小写字母。</p>
<p>1. C++关键字</p>
<p>　　关键字不能用作程序的标识符，标识符不能包含两个连续的下划线，也不能以下划线开头后面紧跟一个大写字母。有些标识符&mdash;&mdash;在函数外定义的标识符&mdash;&mdash;不能以下划线开头。</p>
<p>2. 变量命名习惯</p>
<p>　　变量名一般用小写字母；标识符应使用能帮助记忆的名字；包含多个词的标识符书写为在每个词之间添加一个下划线，或者每个内嵌的词的第一个字母都大写。</p>
<p>2.3.3&nbsp; 定义对象</p>
<p>　　每个定义都是以类型说明符（type specifier）开始，后面紧跟着以逗号分开的含有一个或多个标识符的列表。分号结束定义。</p>
<p>1. 初始化</p>
<p>　　变量定义指定了变量的类型和标识符，也可以为对象提供初始值。C++支持两种初始化变量的形式：拷贝初始化和直接初始化拷贝初始化语法用等号（=），直接初始化是把初始化式放在括号中。</p>
<p>2. 使用多个初始化式</p>
<p>　　对内置类型来说，拷贝初始化和直接初始化几乎没有差别。对类类型的对象来说，有些初始化仅能用直接初始化完成。</p>
<pre>
std::<span style="color: rgb(0, 0, 255);">string</span> all_nines(10, '9');   <span style="color: rgb(0, 128, 0);">// all_nines= &quot;9999999999&quot;</span></pre>
<p>3. 初始化多个变量</p>
<p>　　可以用同一个定义中前面已定义变量的值初始化后面的变量。已初始化变量和未初始化变量可以定义在同一个定义中定义。</p>
<p>2.3.4&nbsp; 变量初始化规则</p>
<p>1. 内置类型变量的初始化</p>
<p>　　内置类型变量是否自动初始化取决于变量定义的位置。在函数体外定义的变量都初始化成0，在函数体里定义的内置类型变量不进行自动初始化。</p>
<p>2. 类类型变量的初始化</p>
<p>　　类通过定义一个或多个构造函数来控制类对象的初始化，如果定义某个类的变量时没有提供初始化式，这个类也可以定义初始化时的操作。它是通过定义一个特殊的构造函数即默认构造函数来实现的。</p>
<p>2.3.5&nbsp; 声明和定义</p>
<p>　　变量的定义为变量分配存储空间，还可以为变量指定初始值。在一个程序中，变量有且仅有一个定义。声明用于向程序表明变量的类型和名字。定义也是声明：当定义变量时我们声明它的类型和名字。可以通过使用extern关键字声明变量名而不定义它。不定义变量的声明包括对象名、对象类型和对象类型前的关键字extern，extern声明不是定义，也不分配存储空间。程序中变量可以声明多次，但只能定义一次。如果声明有初始化式，那么它可被当作是定义，即使声明标记为extern，只有当extern声明位于函数外部时，才可以含有初始化式。</p>
<p>2.3.6 名字的作用域</p>
<p>　　定义在全局作用域中的名字可以在局部作用域中使用，定义在全局作用域中的名字和定义在函数的局部作用域中的名字可以在语句作用域中使用，等等。名字还可以在内部作用域中重新定义。</p>
<p>2.3.7&nbsp; 在变量使用处定义变量</p>
<p>　　通常把一个对象定义在它首次使用的地方是一个很好的办法。</p>
<p>1. 定义const对象</p>
<p>　　因为常量在定义后就不能被修改，所以定义时必须初始化。</p>
<p>2. const对象默认为文件的局部变量</p>
<p>　　把一个非const变量定义在一个文件，假设已经做了合适的声明，就可在另外的文件中使用这个变量：</p>
<pre><span style="color: rgb(0, 128, 0);">// file_1.cc</span>

<span style="color: rgb(0, 0, 255);">int</span> counter;  <span style="color: rgb(0, 128, 0);">// definition</span>

<span style="color: rgb(0, 128, 0);">// file_2.cc</span>

<span style="color: rgb(0, 0, 255);">extern</span> <span style="color: rgb(0, 0, 255);">int</span> counter; <span style="color: rgb(0, 128, 0);">// uses counter from file_1</span></pre>
<pre>
++counter;          <span style="color: rgb(0, 128, 0);">// increments counter defined in file_1</span></pre>
<p>　　除非特别说明，在全局作用域声明的const变量是定义该对象的文件的局部变量。此变量只存在于那个文件，不能被其他文件访问。通过指定const变量为extern，就可以在整个程序中访问const对象：</p>
<pre><span style="color: rgb(0, 128, 0);">// file_1.cc</span>

<span style="color: rgb(0, 128, 0);">// defines and initializes a const that is accessible to other files</span>

<span style="color: rgb(0, 0, 255);">extern</span> <span style="color: rgb(0, 0, 255);">const</span> <span style="color: rgb(0, 0, 255);">int</span> bufSize = fcn();

<span style="color: rgb(0, 128, 0);">// file_2.cc</span>

<span style="color: rgb(0, 0, 255);">extern</span> <span style="color: rgb(0, 0, 255);">const</span> <span style="color: rgb(0, 0, 255);">int</span> bufSize; <span style="color: rgb(0, 128, 0);">// uses bufSize from file_1</span>

<span style="color: rgb(0, 128, 0);">// uses bufSize defined in file_1</span>

<span style="color: rgb(0, 0, 255);">for</span> (<span style="color: rgb(0, 0, 255);">int</span> index = 0; index != bufSize; ++index)

       <span style="color: rgb(0, 128, 0);">// ...</span></pre>
<p>2.5 引用</p>
<p>　　引用主要用作函数的形式参数。</p>
<p>1. 引用是别名</p>
<p>　　因为引用只是它绑定的对象的另一名字，作用在引用上的所有操作事实上都是作用在该引用绑定的对象上。</p>
<p>2. 定义多个引用</p>
<p>3. const引用</p>
<p>　　const引用是指向const对象的引用，将普通的引用绑定到const对象是不合法的。非const引用只能绑定到与该引用同类型的对象，const引用则可以绑定到不同但相关的类型的对象或绑定到右值。</p>
<p>2.6 typedef名字</p>
<p>　　typedef让我们可以定义类型的同义词，typedef名字可以用作类型标识符。typedef通常被用于以下三种目的：</p>
<p>为了隐藏特定类型的实现，强调使用类型的目的。</p>
<p>简化复杂的类型定义，使其更易理解。</p>
<p>允许一种类型用于多个目的，同时使得每次使用该类型的目的明确。</p>
<p>2.7 枚举</p>
<p>1. 定义和初始化枚举</p>
<pre><span style="color: rgb(0, 128, 0);">// input is 0, output is 1, and append is 2</span>

<span style="color: rgb(0, 0, 255);">enum</span> open_modes {input, output, append};</pre>
<p>　　默认地，第一个枚举成员赋值为０，后面的每个枚举成员赋的值比前面的大1。</p>
<p>2. 枚举成员是常量</p>
<p>　　用来初始化枚举成员的值必须是一个常量表达式，枚举成员值可以是不唯一的，不能改变枚举成员的值。</p>
<p>3. 每个enum都定义一种唯一的类型</p>
<p>　　枚举类型的对象的初始化或赋值，只能通过其枚举成员或同一枚举类型的其他对象来进行。</p>
<p>2.8 类类型</p>
<p>1. 设计类从其操作开始</p>
<p>　　每个类都定义了一个接口（interface）和一个实现（implementation）。接口包括我们期望使用该类的代码执行的操作。实现一般包括该类所需要的数据。实现还包括用来定义该类但又不作一般性使用的函数。</p>
<p>2. 定义Sales_item类</p>
<p>　　类定义以关键字class开始，其后是该类的名字标识符。类体位于花括号里面。花括号后面必须要跟一个分号。</p>
<p><font color="#ff0080">编程新手经常会忘记类定义后面的分号，这是个很普遍的错误！</font></p>
<p>　　类也可以包含0个到多个private或public访问标签（access label）。访问标签控制类的成员在类外部是否可访问。使用该类的代码可能只能访问public成员。</p>
<p>　　每一个类都定义了它自己的作用域。也就是说，数据和操作的名字在类的内部必须唯一，但可以重用定义在类外的名字。</p>
<p>3. 类的数据成员</p>
<p>　　一般不能把类成员的初始化作为其定义的一部分，而是通过称为构造函数的特殊成员函数控制初始化。</p>
<p>4. 访问标号</p>
<p>5. 使用struct关键字</p>
<p>　　如果使用class关键字来定义类，那么定义在第一个访问标签前的任何成员都隐式指定为private；如果使用struct关键字，那么这些成员都是public。</p>
<p>2.9 编写自己的头文件</p>
<p>2.9.1&nbsp; 设计自己的头文件</p>
<p>1. 头文件用于声明而不是用于定义</p>
<p>　　对于头文件不应该含有定义这一规则，有三个例外。头文件可以定义类、值在编译时就已知道的const对象和inline函数。</p>
<p>2. 一些const对象定义在头文件中</p>
<p>　　如果const变量不是用常量表达式初始化，那么它就不应该在头文件中定义。</p>
<p>2.9.2&nbsp; 预处理器的简单介绍</p>
<p>1. 头文件经常需要其他头文件</p>
<p>2. 避免多重包含</p>
<p>　　为了避免名字冲突，预处理器变量经常用全大写字母表示。</p>
<pre>
#ifndef SALESITEM_H

#define SALESITEM_H

<span style="color: rgb(0, 128, 0);">// Definition of Sales_item class and related functions goes here</span>

#endif</pre>
<p>　　预处理器变量的名字必须在程序中唯一。任何与预处理器变量相匹配的名字的使用都关联到该预处理器变量。</p>
<p>3. 使用自定义的头文件</p>
<p>　　如果头文件名括在尖括号（&lt; &gt;）里，那么认为该头文件是标准头文件。编译器将会在预定义的位置集查找该头文件，这些预定义的位置可以通过设置查找路径环境变量或者通过命令行选项来修改。如果头文件名括在一对引号里，那么认为它是非系统头文件，非系统头文件的查找通常开始于源文件所在的路径。</p>
<p>&nbsp;</p>
<pre>&nbsp;</pre>
<pre>&nbsp;</pre>
]]></content:encoded>
			<wfw:commentRss>http://klniu.com/post/c-primer-knowledge-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>c++ primer知识点-第1章 快速入门</title>
		<link>http://klniu.com/post/c-primer-knowledge-1/</link>
		<comments>http://klniu.com/post/c-primer-knowledge-1/#comments</comments>
		<pubDate>Sun, 16 Nov 2008 05:56:30 +0000</pubDate>
		<dc:creator>勿慢牛</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[c++ primer]]></category>

		<guid isPermaLink="false">http://livesdrop.com/?p=42</guid>
		<description><![CDATA[第一章 快速入门

目录

1.1 编写简单的C++程序

1.2 初窥输入/输出

1.3 关于注释

1.4 控制结构

1.5 类的简介

1.6 C++程序 <a href="http://klniu.com/post/c-primer-knowledge-1/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>&nbsp;<span style="font-size: x-large;"><span style="font-family: Verdana;">第一章 快速入门</span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: small;"><span style="font-size: medium;"><span style="font-size: large;">目录</span></span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: small;"><span style="font-size: medium;"><span style="font-size: large;">1.1 编写简单的C++程序</span></span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: small;"><span style="font-size: medium;"><span style="font-size: large;">1.2 初窥输入/输出</span></span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: small;"><span style="font-size: medium;"><span style="font-size: large;">1.3 关于注释</span></span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: small;"><span style="font-size: medium;"><span style="font-size: large;">1.4 控制结构</span></span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: small;"><span style="font-size: medium;"><span style="font-size: large;">1.5 类的简介</span></span></span></span></p>
<p><span style="font-family: Verdana;"><span style="font-size: small;"><span style="font-size: medium;"><span style="font-size: large;">1.6 C++程序</span></span></span></span></p>
<p>&nbsp;</p>
<p><span style="font-family: Verdana;"><span style="font-size: small;"><span style="font-size: medium;"><span style="font-size: large;">1.1 编写简单的C++程序</span></span></span></span></p>
<p style="margin-left: 40px;"><span style="font-family: Verdana;"><span style="font-size: large;">每个C++程序都必须有一个main函数。它执行组成自己的语句并返回一个值给操作系统。<br />
</span></span></p>
<p style="margin-left: 40px;"><span style="font-family: Verdana;"><span style="font-size: large;">定义函数必须指定4个元素：返回类型、函数名、圆括号内的形参表（可能为空）和函数体。<br />
</span></span></p>
<p style="margin-left: 40px;"><span style="font-family: Verdana;"><span style="font-size: large;">main函数的返回值必须是int型。<br />
</span></span></p>
<p style="margin-left: 40px;"><span style="font-family: Verdana;"><span style="font-size: large;">函数体是以花括号开始并以花括号结束的语句块。<br />
</span></span></p>
<p style="margin-left: 40px;"><span style="font-family: Verdana;"><span style="font-size: large;">当return带上一个值（如0）时，这个值就是函数的返回值。返回值类型必须和函数的返回类型相同，或者可以转换成函数的返回类型。</span></span></p>
<p><span style="font-size: large;"><span style="font-family: Verdana;">1.2 初窥输入/输出</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">iostream库的基础是两种命名为istream和ostream的类型，分别表示输入流和输出流。流是指要从某种IO设备上读入或写出的字符序列。</span></span></p>
<p><span style="font-size: large;"><span style="font-family: Verdana;">1.2.1 标准输入与输出对象</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">标准输入：处理输入时使用命名为cin的istream类型对象。标准输出：处理输出时使用命名为cout的ostream对象。标准错误：cerr，ostream对象，通常用来输出警告和错误信息给程序的使用者。clog，ostream对象，用于产生程序执行的一般信息。</span></span></p>
<p><span style="font-size: large;"><span style="font-family: Verdana;">1.2.2 一个使用IO库的程序</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">1.写入到流</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">C++中，一个表达式由一个或几个操作数和通常是一个操作符组成。</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">C++中，每个表达式都会产生一个结果，通常是将操作符作用到其操作数所产生的值。当操作符是输出操作符时，结果是左操作数。也就是说，输出操作返回的是值是输出流本身。</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">endl是一个特殊值，称为操纵符，将它写入输出流时，具有输出换行的效果，并刷新与设备相关的缓冲区。通过 刷新缓冲区，用户可立即看到写入到流中的输出。</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">2.使用标准库中的名字</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">前缀std::表明cout和endl是定义在命名空间std中的，该写法使用了作用域操作符。</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">3. 输入流</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">输入操作符作为输出操作符相似，它返回其左操作数作为结果。</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">4. 完成程序</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">在C++程序中，大部分出现空格符的地方可用换行符代替。这条规则的一个例外是字符串字面值中的空格符不能用换行符代替。另一个例外是空格符不允许出现在预处理指示中。</span></span></p>
<p><span style="font-size: large;"><span style="font-family: Verdana;">1.3 关于注释</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">C++有单行注释和成对注释两种类型的注释，单行注释以双斜线（//）开头，行中处于双斜线右边的内容是注释，被编译器忽略，另一种定界符，注释对(/* */)，注释对不可嵌套。</span></span></p>
<p><span style="font-size: large;"><span style="font-family: Verdana;">1.4 控制结构</span></span></p>
<p><span style="font-size: large;"><span style="font-family: Verdana;">1.4.1 while语句</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">while结构：while (condition) while_body_statement</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">复合赋值操作符(+=操作符)，这个操作符把它的右操作符加至左操作数，这等效于编写含一个加法和一个赋值的语句。</span></span></p>
<p><span style="font-size: large;"><span style="font-family: Verdana;">1.4.2 for语句</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">for语句头由三部分组成：一个初始化语句，一个条件，一个表达式。</span></span></p>
<p><span style="font-size: large;"><span style="font-family: Verdana;">1.4.3 if语句</span></span></p>
<p><span style="font-size: large;"><span style="font-family: Verdana;">1.4.4 读入未知数目的输入</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">当我们使用istream对象作为条件，结果是测试流的状态。如果流是有效的（也就是说，如果读入下一个输入是可能的），那么测试成功。遇到文件结束符(end-of-file)或遇到无数输入时，如果读取了一个不是整数的值，则istream对象是无效的。处于无效状态的istream对象将导致条件失败。</span></span></p>
<p><span style="font-size: large;"><span style="font-family: Verdana;">1.5 类的简介</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">使用类时我们需要回答三个问题：</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">&nbsp;(1) 类的名字是什么？<br />
</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">(2) 它在哪里定义？<br />
</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">(3) 它支持什么操作？<br />
</span></span></p>
<p><span style="font-size: large;"><span style="font-family: Verdana;">1.5.1 Sales_item类<br />
</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">包含存储类类型的文件。<br />
</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">1.Sales_item对象上的操作<br />
</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">每个类定义一种类型，类型名与类名相同，可以这样定义类类型的变量：Sales_item item;<br />
</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">2. 读入和写出Sales_item对象<br />
</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">标准库的头文件用尖括号&lt;&gt;括起来，非标准库的头文件用&ldquo; &ldquo;括起来。<br />
</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">3. 将Sales_item对象相加<br />
</span></span></p>
<p style="margin-left: 40px;"><span style="font-size: large;"><span style="font-family: Verdana;">成员函数是由类定义的函数，有时称为类方法。当调用成员函数时，（通常）指定函数要操作的对象，语法是使用点操作符(.)，意思是&ldquo;命名为item1的对象的Sales_isbn成员&rdquo;。点操作符通过它的左操作数取得右操作数。点操作符仅应用于类类型的对象：左操作必须是类类型的对象，右操作必须指定该类型的成员。<br />
</span></span></p>
<p><span style="font-size: large;"><span style="font-family: Verdana;">1.6 C++程序</span></span></p>
]]></content:encoded>
			<wfw:commentRss>http://klniu.com/post/c-primer-knowledge-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

