<?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>Dutor &#187; 之语言特性</title>
	<atom:link href="http://www.dutor.net/index.php/category/program/language/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.dutor.net</link>
	<description>大师兄，师傅被妖怪抓走啦！</description>
	<lastBuildDate>Thu, 09 Sep 2010 00:37:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>const在C和C++中的区别</title>
		<link>http://www.dutor.net/index.php/2010/08/const-c-cpp-difference/</link>
		<comments>http://www.dutor.net/index.php/2010/08/const-c-cpp-difference/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 13:50:48 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[const]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=2408</guid>
		<description><![CDATA[　　const在C，尤其是C++，是个老生常谈的问题，但这里不谈const具体有哪些特性，如何使用，而是说说const在C和C++中的区别。编译器，C使用gcc，C++使用g++，其它编译器（cl等）请自行验证。
　　在我的印象中，const就是<strong>常量</strong>（<em>const</em>ant）。但这并不是真的。在C中，const仅仅表示其所修饰对象<strong>不可修改</strong>。常量和所谓“不可修改”有什么区别呢？C中，const int N = 10; 这样的语句声明了一个<strong>整型数据</strong>，声明之后你不能再为其赋值，此即为<strong>不可修改</strong>。但在C中，N却不是常量，而诸如372, 3.72, 'A'之类才是常量，在C中定义常量通常使用#define。而在C++中，const int N = 10; 就会定义N为常量。
　　怎么证明呢？你可能知道，定义静态数组，必须使用整型常量指定其大小，那咱们就用这个特性来验证上面描述的观点。
<pre lang="c" line="1">
int
main(int argc, char **argv)
{
    const int N = 10;
    int a[N] = { 1, 2, 3 };
    return 0;
}
</pre>]]></description>
			<content:encoded><![CDATA[<p>　　const在C，尤其是C++，是个老生常谈的问题，但这里不谈const具体有哪些特性，如何使用，而是说说const在C和C++中的区别。编译器，C使用gcc，C++使用g++，其它编译器（cl等）请自行验证。<br />
　　在我的印象中，const就是<strong>常量</strong>（<em>const</em>ant）。但这并不是真的。在C中，const仅仅表示其所修饰对象<strong>不可修改</strong>。常量和所谓“不可修改”有什么区别呢？C中，const int N = 10; 这样的语句声明了一个<strong>整型数据</strong>，声明之后你不能再为其赋值，此即为<strong>不可修改</strong>。但在C中，N却不是常量，而诸如372, 3.72, &#8216;A&#8217;之类才是常量，在C中定义常量通常使用#define。而在C++中，const int N = 10; 就会定义N为常量。<br />
　　怎么证明呢？你可能知道，定义静态数组，必须使用整型常量指定其大小，那咱们就用这个特性来验证上面描述的观点。</p>

<div class="wp_codebox"><table><tr id="p24081"><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code" id="p2408code1"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span>
main<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> argc<span style="color: #339933;">,</span> <span style="color: #993333;">char</span> <span style="color: #339933;">**</span>argv<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">const</span> <span style="color: #993333;">int</span> N <span style="color: #339933;">=</span> <span style="color: #0000dd;">10</span><span style="color: #339933;">;</span>
    <span style="color: #993333;">int</span> a<span style="color: #009900;">&#91;</span>N<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">3</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>　　使用g++编译这个程序，没有问题。但若使用gcc，你会得到如下错误信息</p>
<pre>
main.c: In function ‘main’:
main.c:19: error: variable-sized object may not be initialized
main.c:19: warning: excess elements in array initializer
</pre>
<p>　　<br />
　　但事情并未到此结束，如果你把上面代码中int a[N] = { 1, 2, 3 };的初始化列表去掉，即int a[N]; 然后就也能通过gcc的编译，更有甚者，如果你把const int N = 10;的const去掉：int N = 10; 也能通过gcc的编译！这是gcc所支持的特性，即<strong>动态数组</strong>。但最好不要这样做，因为gcc会为此生成大量代码。例如，这段代码</p>

<div class="wp_codebox"><table><tr id="p24082"><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code" id="p2408code2"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span>
main<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> argc<span style="color: #339933;">,</span> <span style="color: #993333;">char</span> <span style="color: #339933;">**</span>argv<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">const</span> <span style="color: #993333;">int</span> N <span style="color: #339933;">=</span> <span style="color: #0000dd;">10</span><span style="color: #339933;">;</span>
    <span style="color: #993333;">int</span> a<span style="color: #009900;">&#91;</span>N<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>使用gcc生成的汇编代码：</p>

<div class="wp_codebox"><table><tr id="p24083"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
</pre></td><td class="code" id="p2408code3"><pre class="asm" style="font-family:monospace;">&nbsp;
	<span style="color: #339933;">.</span>file	<span style="color: #7f007f;">&quot;main.c&quot;</span>
	<span style="color: #339933;">.</span>text
<span style="color: #339933;">.</span>globl main
	<span style="color: #339933;">.</span><span style="color: #000000; font-weight: bold;">type</span>	main<span style="color: #339933;">,</span> @function
main<span style="color: #339933;">:</span>
	leal	<span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">ecx</span>
	andl	$<span style="color: #339933;">-</span><span style="color: #0000ff;">16</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">esp</span>
	pushl	<span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ecx</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	pushl	<span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span>
	movl	<span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span>
	pushl	<span style="color: #339933;">%</span><span style="color: #00007f;">esi</span>
	pushl	<span style="color: #339933;">%</span><span style="color: #00007f;">ebx</span>
	pushl	<span style="color: #339933;">%</span><span style="color: #00007f;">ecx</span>
	subl	$<span style="color: #0000ff;">60</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">esp</span>
	movl	<span style="color: #339933;">%</span><span style="color: #00007f;">ecx</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	movl	<span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">eax</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	movl	<span style="color: #339933;">%</span><span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">44</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	movl	<span style="color: #339933;">%</span><span style="color: #00007f;">gs</span><span style="color: #339933;">:</span><span style="color: #0000ff;">20</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	movl	<span style="color: #339933;">%</span><span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">28</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
<span style="color: #009900; font-weight: bold;">&#91;</span> <span style="color: #339933;">...</span> <span style="color: #009900; font-weight: bold;">&#93;</span> # 此处略去n行
	movl	<span style="color: #339933;">%</span><span style="color: #00007f;">ecx</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">esp</span>
	movl	<span style="color: #339933;">-</span><span style="color: #0000ff;">28</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">edx</span>
	xorl	<span style="color: #339933;">%</span><span style="color: #00007f;">gs</span><span style="color: #339933;">:</span><span style="color: #0000ff;">20</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">edx</span>
	<span style="color: #00007f; font-weight: bold;">je</span>	<span style="color: #339933;">.</span>L3
	<span style="color: #00007f; font-weight: bold;">call</span>	__stack_chk_fail
<span style="color: #339933;">.</span>L3<span style="color: #339933;">:</span>
	leal	<span style="color: #339933;">-</span><span style="color: #0000ff;">12</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">esp</span>
	addl	$<span style="color: #0000ff;">0</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">esp</span>
	popl	<span style="color: #339933;">%</span><span style="color: #00007f;">ecx</span>
	popl	<span style="color: #339933;">%</span><span style="color: #00007f;">ebx</span>
	popl	<span style="color: #339933;">%</span><span style="color: #00007f;">esi</span>
	popl	<span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span>
	leal	<span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ecx</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">esp</span>
	<span style="color: #00007f; font-weight: bold;">ret</span></pre></td></tr></table></div>

<p>　　整个汇编文件有96行之多。而使用g++（<strong>N为常量</strong>）编译生成的汇编文件只有23行：</p>

<div class="wp_codebox"><table><tr id="p24084"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
</pre></td><td class="code" id="p2408code4"><pre class="asm" style="font-family:monospace;">	<span style="color: #339933;">.</span>file	<span style="color: #7f007f;">&quot;main.c&quot;</span>
	<span style="color: #339933;">.</span>text
<span style="color: #339933;">.</span>globl main
	<span style="color: #339933;">.</span><span style="color: #000000; font-weight: bold;">type</span>	main<span style="color: #339933;">,</span> @function
main<span style="color: #339933;">:</span>
<span style="color: #339933;">.</span>LFB0<span style="color: #339933;">:</span>
	<span style="color: #339933;">.</span>cfi_startproc
	<span style="color: #339933;">.</span>cfi_personality <span style="color: #0000ff;">0x0</span><span style="color: #339933;">,</span>__gxx_personality_v0
	pushl	<span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span>
	<span style="color: #339933;">.</span>cfi_def_cfa_offset <span style="color: #0000ff;">8</span>
	movl	<span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span>
	<span style="color: #339933;">.</span>cfi_offset <span style="color: #0000ff;">5</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span>
	<span style="color: #339933;">.</span>cfi_def_cfa_register <span style="color: #0000ff;">5</span>
	subl	$<span style="color: #0000ff;">48</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">esp</span>
	movl	$<span style="color: #0000ff;">10</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	movl	$<span style="color: #0000ff;">0</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	<span style="color: #00007f; font-weight: bold;">leave</span>
	<span style="color: #00007f; font-weight: bold;">ret</span>
	<span style="color: #339933;">.</span>cfi_endproc
<span style="color: #339933;">.</span>LFE0<span style="color: #339933;">:</span>
	<span style="color: #339933;">.</span><span style="color: #000000; font-weight: bold;">size</span>	main<span style="color: #339933;">,</span> <span style="color: #339933;">.-</span>main
	<span style="color: #339933;">.</span>ident	<span style="color: #7f007f;">&quot;GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3&quot;</span>
	<span style="color: #339933;">.</span>section	<span style="color: #339933;">.</span>note<span style="color: #339933;">.</span>GNU<span style="color: #339933;">-</span><span style="color: #000000; font-weight: bold;">stack</span><span style="color: #339933;">,</span><span style="color: #7f007f;">&quot;&quot;</span><span style="color: #339933;">,</span>@progbits</pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2010/08/const-c-cpp-difference/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>[C/C++]volatile</title>
		<link>http://www.dutor.net/index.php/2010/08/volatile-const/</link>
		<comments>http://www.dutor.net/index.php/2010/08/volatile-const/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 12:05:25 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[const]]></category>
		<category><![CDATA[volatile]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=2387</guid>
		<description><![CDATA[<h4>volatile</h4>
　　可能很多人都没用过<span class="word">C/C++</span>中的这个关键词，甚至不知道它的存在，本人以前也只是有所耳闻，但似懂非懂。
　　这是一个<strong>类型修饰符</strong>，位置同<span class="word">const</span>、<span class="word">static</span>等。一个使用<span class="word">volatile</span>修饰的变量，比如<em><span class="word">volatile int i;</span> </em>每次对该变量的直接引用，都会访问内存，而不是从寄存器中读取（如果其已经在寄存器中）。这样一来，<span class="word">volatile</span>似乎没什么用处，反倒会使数据的读取相对变慢很多。但是，如果没有<span class="word">volatile</span>，编译器可能会优化你的程序，使得数据从寄存器中读取，从而加快程序的运行，但如果这个变量是同其它进程/线程<strong>共享</strong>的，就可能造成数据的不一致。多线程情况下，你可以使用互斥机制来保证对共享数据访问的原子性。但是，在单片机等嵌入式环境中，硬件经常不会有这种<strong>互斥机制</strong>的支持，这时某些共享的数据（比如端口）就可能会产生不一致的情况。而使用<span class="word">volatile</span>就会使编译器不对代码进行优化，每次对该变量的访问都会从内存中读取。
　　下面通过观察使用<span class="word">volatile</span>前后编译产生的汇编代码的不同，来加深对<span class="word">volatile</span>关键词的理解。
<pre lang="asm" line="1">
[ ... ]
main:
[ ... ]
	call	foo # 调用函数foo，返回值保存至寄存器eax
	movl	%eax, 44(%esp) # 为i赋值
	movl	44(%esp), %edx # 读取i值
	movl	44(%esp), %ecx # 读取i值
	movl	44(%esp), %eax # 读取i值
	movl	%ecx, 16(%esp) # 参数k入栈，使用i值
	movl	%edx, 12(%esp) # 参数j入栈，使用i值
	movl	%eax, 8(%esp) # 参数i入栈
	movl	$.LC0, 4(%esp) # 格式字符串地址入栈
	call	__printf_chk
	movl	$0, %eax
	leave
	ret
[ ... ]
</pre>]]></description>
			<content:encoded><![CDATA[<h4>volatile</h4>
<p>　　可能很多人都没用过<span class="word">C/C++</span>中的这个关键词，甚至不知道它的存在，本人以前也只是有所耳闻，但似懂非懂。<br />
　　这是一个<strong>类型修饰符</strong>，位置同<span class="word">const</span>、<span class="word">static</span>等。一个使用<span class="word">volatile</span>修饰的变量，比如<em><span class="word">volatile int i;</span> </em>每次对该变量的直接引用，都会访问内存，而不是从寄存器中读取（如果其已经在寄存器中）。这样一来，<span class="word">volatile</span>似乎没什么用处，反倒会使数据的读取相对变慢很多。但是，如果没有<span class="word">volatile</span>，编译器可能会优化你的程序，使得数据从寄存器中读取，从而加快程序的运行，但如果这个变量是同其它进程/线程<strong>共享</strong>的，就可能造成数据的不一致。多线程情况下，你可以使用互斥机制来保证对共享数据访问的原子性。但是，在单片机等嵌入式环境中，硬件经常不会有这种<strong>互斥机制</strong>的支持，这时某些共享的数据（比如端口）就可能会产生不一致的情况。而使用<span class="word">volatile</span>就会使编译器不对代码进行优化，每次对该变量的访问都会从内存中读取。<br />
　　下面通过观察使用<span class="word">volatile</span>前后编译产生的汇编代码的不同，来加深对<span class="word">volatile</span>关键词的理解。<br />
　　对于下面的<span class="word">C</span>代码：</p>

<div class="wp_codebox"><table><tr id="p23875"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code" id="p2387code5"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;stdio.h&gt;</span>
&nbsp;
<span style="color: #0000ff;">int</span> foo<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span>i<span style="color: #000040;">++</span> <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">20</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> i<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">int</span>
main<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> argc, <span style="color: #0000ff;">char</span> <span style="color: #000040;">**</span>argv<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> foo<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">int</span> j <span style="color: #000080;">=</span> i<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">int</span> k <span style="color: #000080;">=</span> i<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">printf</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;%d, %d, %d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, i, j, k<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>　　代码中，使用<em>foo()</em>的返回值（20）来初始化整型变量<span class="word">i</span>。之所以不直接赋值，是为了<strong>防止</strong>编译器优化，下面对<span class="word">j,k</span>的赋值将直接使用<span class="word">20</span>，而不是<span class="word">i</span>，也不是寄存器。使用下面的命令编译：</p>

<div class="wp_codebox"><table><tr id="p23876"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p2387code6"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">gcc</span> <span style="color: #660033;">-S</span> <span style="color: #660033;">-O1</span> main.c <span style="color: #666666; font-style: italic;"># 优化等级1</span></pre></td></tr></table></div>

<p>　　产生的汇编代码：</p>

<div class="wp_codebox"><table><tr id="p23877"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code" id="p2387code7"><pre class="asm" style="font-family:monospace;"><span style="color: #009900; font-weight: bold;">&#91;</span> <span style="color: #339933;">...</span> <span style="color: #009900; font-weight: bold;">&#93;</span>
<span style="color: #339933;">.</span>LC0<span style="color: #339933;">:</span>
	<span style="color: #339933;">.</span>string	<span style="color: #7f007f;">&quot;%d, %d, %d\n&quot;</span>
<span style="color: #009900; font-weight: bold;">&#91;</span> <span style="color: #339933;">...</span> <span style="color: #009900; font-weight: bold;">&#93;</span>
main<span style="color: #339933;">:</span>
<span style="color: #009900; font-weight: bold;">&#91;</span> <span style="color: #339933;">...</span> <span style="color: #009900; font-weight: bold;">&#93;</span>
	<span style="color: #00007f; font-weight: bold;">call</span>	foo # 调用函数foo，返回值保存至寄存器<span style="color: #00007f;">eax</span>
	movl	<span style="color: #339933;">%</span><span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">16</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span> # 参数k入栈
	movl	<span style="color: #339933;">%</span><span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">12</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span> # 参数j入栈
	movl	<span style="color: #339933;">%</span><span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span> # 参数i入栈
	movl	$<span style="color: #339933;">.</span>LC0<span style="color: #339933;">,</span> <span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span> # 格式字符串地址入栈
	movl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	<span style="color: #00007f; font-weight: bold;">call</span>	__printf_chk
	movl	$<span style="color: #0000ff;">0</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	<span style="color: #00007f; font-weight: bold;">leave</span>
	<span style="color: #00007f; font-weight: bold;">ret</span>
<span style="color: #009900; font-weight: bold;">&#91;</span> <span style="color: #339933;">...</span> <span style="color: #009900; font-weight: bold;">&#93;</span></pre></td></tr></table></div>

<p>　　可以看到，对<span class="word">j,k</span>的赋值都是由寄存器<span class="word">eax</span>进行的。下面把代码中的<em><span class="word">int i = foo();</span></em>换成<em><span class="word">volatile int i = foo();</span></em>，编译得到的汇编代码是：</p>

<div class="wp_codebox"><table><tr id="p23878"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code" id="p2387code8"><pre class="asm" style="font-family:monospace;"><span style="color: #009900; font-weight: bold;">&#91;</span> <span style="color: #339933;">...</span> <span style="color: #009900; font-weight: bold;">&#93;</span>
main<span style="color: #339933;">:</span>
<span style="color: #009900; font-weight: bold;">&#91;</span> <span style="color: #339933;">...</span> <span style="color: #009900; font-weight: bold;">&#93;</span>
	<span style="color: #00007f; font-weight: bold;">call</span>	foo # 调用函数foo，返回值保存至寄存器<span style="color: #00007f;">eax</span>
	movl	<span style="color: #339933;">%</span><span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">44</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span> # 为i赋值
	movl	<span style="color: #0000ff;">44</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">edx</span> # 读取i值
	movl	<span style="color: #0000ff;">44</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">ecx</span> # 读取i值
	movl	<span style="color: #0000ff;">44</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span> # 读取i值
	movl	<span style="color: #339933;">%</span><span style="color: #00007f;">ecx</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">16</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span> # 参数k入栈，使用i值
	movl	<span style="color: #339933;">%</span><span style="color: #00007f;">edx</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">12</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span> # 参数j入栈，使用i值
	movl	<span style="color: #339933;">%</span><span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span> # 参数i入栈
	movl	$<span style="color: #339933;">.</span>LC0<span style="color: #339933;">,</span> <span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span> # 格式字符串地址入栈
	<span style="color: #00007f; font-weight: bold;">call</span>	__printf_chk
	movl	$<span style="color: #0000ff;">0</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	<span style="color: #00007f; font-weight: bold;">leave</span>
	<span style="color: #00007f; font-weight: bold;">ret</span>
<span style="color: #009900; font-weight: bold;">&#91;</span> <span style="color: #339933;">...</span> <span style="color: #009900; font-weight: bold;">&#93;</span></pre></td></tr></table></div>

<p>　　可以看到，每次对i的访问都是从内存（栈）中读取的。</p>
<h4>volatile vs. const</h4>
<p>　　正像上面所描述的那样，<span class="word">volatile</span>的意思是<strong>“易变的”</strong>。<span class="word">C/C++</span>中还有另外一个关键词叫<span class="word">const</span>，用来限定变量不可被改变。似乎volatile和const意思相反，水火不容。但<span class="word"><em>volatile const int N = 0;</em></span>这样的语句是允许存在的。为什么呢？其实，这个语句可以这样来理解：变量<span class="word">N</span>在本程序（或者设备）中是不可（禁止）改变的，但它可能会被其它程序（或者设备）改变。你或许知道，<span class="word">const</span>只是编译器的限定，而没有执行期的检查，因此<span class="word">const</span>也只是限于单个进程，因此<span class="word">volatile</span>和<span class="word">const</span>这两个关键词并不冲突。<br />
　　另外，普通的整型<span class="word">const</span>变量，比如<em><span class="word">const int N = 10; int a[N];</span></em> 中，变量<span class="word">N</span>可能并不会被分配内存（除非程序里面有显式使用N地址的表达式）。但是，根据<span class="word">volatile</span>变量的特性，<em><span class="word">volatile const int N = 10;</span></em>中变量<span class="word">N</span>是一定会占用内存的。这一点，亦可以通过观察相应的汇编代码来验证。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2010/08/volatile-const/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>qsort</title>
		<link>http://www.dutor.net/index.php/2010/07/qsort/</link>
		<comments>http://www.dutor.net/index.php/2010/07/qsort/#comments</comments>
		<pubDate>Tue, 06 Jul 2010 12:57:10 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[qsort]]></category>
		<category><![CDATA[排序]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=2347</guid>
		<description><![CDATA[　　对qsort需要注意几点：
<ul>
	<li>qsort中第一个参数是待排序数组的开始地址，既然是数组，各元素就是同类型、同大小的对象，且数组是<strong>“一维数组”</strong>（即地址是连续的）；</li>
	<li>qsort用以区分对象的依据是第二和第三个参数，分别表示对象个数和每个对象的大小（字节）；</li>
	<li>qsort并不知道每个对象的类型和结构，排序准则由用户在第四个参数（比较函数）中指出，qsort按该比较函数准则的“升序”对数组进行排序；</li>
	<li>标准C不支持运算符重载，各对象的交换（因为这是qsort）靠的是逐字节的拷贝（memcpy?）。</li>
</ul>
　　在上面的两片代码中，待排序的对象一个是字符型指针，一个是char (*)[10]型数组。然后，就没有然后了。]]></description>
			<content:encoded><![CDATA[<p>　　Felix那里看到的，关于用qsort对指针式字符串数组和二维型字符串数组的排序的，觉得值得贴出来。注意下下面两片代码的区别。</p>

<div class="wp_codebox"><table><tr id="p23479"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td class="code" id="p2347code9"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">const</span> <span style="color: #993333;">int</span> N <span style="color: #339933;">=</span> <span style="color: #0000dd;">4</span><span style="color: #339933;">;</span>
<span style="color: #993333;">char</span> <span style="color: #339933;">*</span>str<span style="color: #009900;">&#91;</span>N<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #ff0000;">&quot;xyz&quot;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;cdef&quot;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;abcd&quot;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;caaa&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #993333;">int</span> cmp<span style="color: #009900;">&#40;</span><span style="color: #993333;">const</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>l<span style="color: #339933;">,</span> <span style="color: #993333;">const</span> <span style="color: #993333;">void</span> <span style="color: #339933;">*</span>r<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>a <span style="color: #339933;">=</span> <span style="color: #339933;">*</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span><span style="color: #339933;">**</span><span style="color: #009900;">&#41;</span>l<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #993333;">const</span> <span style="color: #993333;">char</span> <span style="color: #339933;">*</span>b <span style="color: #339933;">=</span> <span style="color: #339933;">*</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span><span style="color: #339933;">**</span><span style="color: #009900;">&#41;</span>r<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> strcmp<span style="color: #009900;">&#40;</span>a<span style="color: #339933;">,</span> b<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #993333;">int</span>
main<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> argc<span style="color: #339933;">,</span> <span style="color: #993333;">char</span> <span style="color: #339933;">**</span>argv<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    qsort<span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>str<span style="color: #339933;">,</span> N<span style="color: #339933;">,</span> <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> cmp <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> N<span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> str<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>


<div class="wp_codebox"><table><tr id="p234710"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code" id="p2347code10"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">const</span> <span style="color: #993333;">int</span> N <span style="color: #339933;">=</span> <span style="color: #0000dd;">4</span><span style="color: #339933;">;</span>
<span style="color: #993333;">char</span> str<span style="color: #009900;">&#91;</span>N<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">10</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #ff0000;">&quot;xyz&quot;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;cdef&quot;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;abcd&quot;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;caaa&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #993333;">int</span>
main<span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> argc<span style="color: #339933;">,</span> <span style="color: #993333;">char</span> <span style="color: #339933;">**</span>argv<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    qsort<span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span>str<span style="color: #339933;">,</span> N<span style="color: #339933;">,</span>
            <span style="color: #993333;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">char</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">*</span><span style="color: #0000dd;">10</span><span style="color: #339933;">,</span>
            <span style="color: #009900;">&#40;</span> <span style="color: #993333;">int</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">const</span> <span style="color: #993333;">void</span><span style="color: #339933;">*,</span> <span style="color: #993333;">const</span> <span style="color: #993333;">void</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>strcmp <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span> i <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> N<span style="color: #339933;">;</span> <span style="color: #339933;">++</span>i<span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> str<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>　　对qsort需要注意几点：</p>
<ul>
<li>qsort中第一个参数是待排序数组的开始地址，既然是数组，各元素就是同类型、同大小的对象，且数组是<strong>“一维数组”</strong>（即地址是连续的）；</li>
<li>qsort用以区分对象的依据是第二和第三个参数，分别表示对象个数和每个对象的大小（字节）；</li>
<li>qsort并不知道每个对象的类型和结构，排序准则由用户在第四个参数（比较函数）中指出，qsort按该比较函数准则的“升序”对数组进行排序；</li>
<li>标准C不支持运算符重载，各对象的交换（因为这是qsort）靠的是逐字节的拷贝（memcpy?）。</li>
</ul>
<p>　　在上面的两片代码中，待排序的对象一个是字符型指针，一个是char (*)[10]型数组。然后，就没有然后了。<br />
　　<br />
　　然后，上面代码，gcc编译出错，g++却可以。<br />
　　const int N = 4; char *str[N];可以。<br />
　　const int N = 4; char *str[N] = {&#8220;a&#8221;,&#8221;b&#8221;,&#8221;c&#8221;,&#8221;d&#8221;};却不可，何解？</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2010/07/qsort/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>struct/class关键字何时是必须的？</title>
		<link>http://www.dutor.net/index.php/2010/05/is-struct-class-necessary/</link>
		<comments>http://www.dutor.net/index.php/2010/05/is-struct-class-necessary/#comments</comments>
		<pubDate>Fri, 21 May 2010 13:16:54 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Cpp]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=2288</guid>
		<description><![CDATA[　　在形如struct structName varName;的语句中，struct是必须的吗？这是一个显而易见的语法问题，但却容易被忽略，尤其容易被C+C++的同志们忽略。
　　在标准C中，struct关键字是必须的：
<pre lang="c" line="1">
struct structName {
    int n;
};
//~ typedef struct structName structName;
int
main()
{
    struct structName n;
    return 0;
}
</pre>
若没有前置的struct关键字，上面的代码就不能通过编译。我的gcc会提示"structName" undeclared, parse error before 'n'的错误。为了方便，通常会使用typedef struct structName structName;语句来为struct structName定义类型别名。
　　但是，在C++中，一般情况下，struct/class关键字就不是必须的。但是，在有些情况下struct/class关键字又是必须的，因为这时的名字structName有歧义性。这是因为，C/C++语言允许用户自定义类型和函数同名。]]></description>
			<content:encoded><![CDATA[<p>　　在形如struct structName varName;的语句中，struct是必须的吗？这是一个显而易见的语法问题，但却容易被忽略，尤其容易被C+C++的同志们忽略。<br />
　　在标准C中，struct关键字是必须的：</p>

<div class="wp_codebox"><table><tr id="p228811"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code" id="p2288code11"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">struct</span> structName <span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">int</span> n<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">//~ typedef struct structName structName;</span>
<span style="color: #993333;">int</span>
main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">struct</span> structName n<span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>若没有前置的struct关键字，上面的代码就不能通过编译。我的gcc会提示&#8221;structName&#8221; undeclared, parse error before &#8216;n&#8217;的错误。为了方便，通常会使用typedef struct structName structName;语句来为struct structName定义类型别名。<br />
　　但是，在C++中，一般情况下，struct/class关键字就不是必须的。但是，在有些情况下struct/class关键字又是必须的，因为这时的名字structName有歧义性。这是因为，C/C++语言允许用户自定义类型和函数同名。</p>

<div class="wp_codebox"><table><tr id="p228812"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="p2288code12"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">struct</span> structName <span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">int</span> n<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #993333;">void</span> structName<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #993333;">int</span>
main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    structName n<span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>上面代码，无论使用gcc还是g++，都不能通过编译，即使structName n;明显只能是一个变量定义语句。这时，就需要明确使用关键字struct，即struct structName n;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2010/05/is-struct-class-necessary/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[STL]函数对象/仿函数</title>
		<link>http://www.dutor.net/index.php/2010/04/stl-functor-function-object/</link>
		<comments>http://www.dutor.net/index.php/2010/04/stl-functor-function-object/#comments</comments>
		<pubDate>Thu, 29 Apr 2010 12:37:46 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[STL]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=2209</guid>
		<description><![CDATA[　　提到C++ STL，首先被人想到的是它的三大组件：Containers, Iterators, Algorithms，即容器，迭代器和算法。容器为用户提供了常用的数据结构，算法大多是独立于容器的常用的基本算法，迭代器是由容器提供的一种接口，算法通过迭代器来操控容器。接下来要介绍的是另外的一种组件，函数对象（Function Object，JJHou译作Functor仿函数）。
<h4>什么是函数对象</h4>
　　顾名思义，函数对象首先是一个对象，即某个类的实例。其次，函数对象的行为和函数一致，即是说可以像调用函数一样来使用函数对象，如参数传递、返回值等。这种行为是通过重载类的()操作符来实现的，举例说明之，
<pre lang="cpp" line="1">
class Print
{
public:
    void operator()(int n)
    {
        std::cout<<n<<std::endl;
        return ;
    }
};
int
main(int argc, char **argv)
{
    Print print;
    print(372);
    print.operator()(372); //~ 显式调用
    return 0;
}
</pre>]]></description>
			<content:encoded><![CDATA[<p>　　提到C++ STL，首先被人想到的是它的三大组件：Containers, Iterators, Algorithms，即容器，迭代器和算法。容器为用户提供了常用的数据结构，算法大多是独立于容器的常用的基本算法，迭代器是由容器提供的一种接口，算法通过迭代器来操控容器。接下来要介绍的是另外的一种组件，函数对象（Function Object，JJHou译作Functor仿函数）。</p>
<h4>什么是函数对象</h4>
<p>　　顾名思义，函数对象首先是一个对象，即某个类的实例。其次，函数对象的行为和函数一致，即是说可以像调用函数一样来使用函数对象，如参数传递、返回值等。这种行为是通过重载类的()操作符来实现的，举例说明之，</p>

<div class="wp_codebox"><table><tr id="p220913"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code" id="p2209code13"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> Print
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    <span style="color: #0000ff;">void</span> operator<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span><span style="color: #000080;">&lt;&lt;</span>n<span style="color: #000080;">&lt;&lt;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">return</span> <span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">int</span>
main<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> argc, <span style="color: #0000ff;">char</span> <span style="color: #000040;">**</span>argv<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    Print print<span style="color: #008080;">;</span>
    print<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">372</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    print.<span style="color: #007788;">operator</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">372</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">//~ 显式调用</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>　　其实我们早就开始使用函数对象了，当你写下sort(v.begin(), v.end())时(假定v是vector&lt;int&gt;)，其实调用的是sort(v.begin(), v.end(), less&lt;int&gt;())，这样sort就会将v从小至大排序。若要逆向排序，你就需要显式地为sort指定一个排序规则，即函数对象greater&lt;int&gt;(). less&lt;T&gt;和greater&lt;T&gt;是STL中的两个模板类，它们使用类型T的&lt;和&gt;操作符。less&lt;T&gt;的一个典型实现可能是这样的：</p>

<div class="wp_codebox"><table><tr id="p220914"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code" id="p2209code14"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> T<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">class</span> less
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    <span style="color: #0000ff;">bool</span> operator<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span>l, <span style="color: #0000ff;">const</span> T<span style="color: #000040;">&amp;</span>r<span style="color: #008000;">&#41;</span><span style="color: #0000ff;">const</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">return</span> l <span style="color: #000080;">&lt;</span> r<span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<h4>函数对象的分类</h4>
<p>　　根据用途和参数特征，STL中的函数对象通常分为以下几类：Predicates, Arithmetic Function Objects, Binders, Negaters, Member Function Adapters, Pointer to Function Adapters。下面逐一介绍一下，之前得先介绍两个基类：</p>

<div class="wp_codebox"><table><tr id="p220915"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code" id="p2209code15"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">template</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> Arg, <span style="color: #0000ff;">class</span> Res<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">struct</span> unary_function <span style="color: #666666;">//~ 一元函数对象基类</span>
<span style="color: #008000;">&#123;</span>
   <span style="color: #0000ff;">typedef</span> Arg argument_type<span style="color: #008080;">;</span>
   <span style="color: #0000ff;">typedef</span> Res result_type<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">template</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> Arg1, <span style="color: #0000ff;">class</span> Arg2, <span style="color: #0000ff;">class</span> Res<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">struct</span> binary_function <span style="color: #666666;">//~ 二元函数对象基类</span>
<span style="color: #008000;">&#123;</span>
   <span style="color: #0000ff;">typedef</span> Arg1 first_argument_type<span style="color: #008080;">;</span>
   <span style="color: #0000ff;">typedef</span> Arg2 second_argument_type<span style="color: #008080;">;</span>
   <span style="color: #0000ff;">typedef</span> Res  result_type<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>使用这两个基类，首先需要包含头文件<functional>。</p>
<h5>Predicates</h5>
<p>　　Predicate是一种函数对象，返回值（应该是operator()的返回值）为布尔型，接受一个或者两个参数。通常用来判断对象的有效性（一个参数时）或者对两个对象进行比较（如less）。你可以根据自己的需要定义自己的Predicate，但STL已经定义了一些Predicate，你可以直接使用。</p>
<table>
<caption>Predicates</caption>
<tr>
<th>Predicate</th>
<th>类型</th>
<th>描述</th>
</tr>
<tr>
<td>equal_to<type>()</td>
<td>Binary</td>
<td>使用==判等</td>
</tr>
<tr>
<td>not_equal_to<type>()</td>
<td>Binary</td>
<td>使用!=判等</td>
</tr>
<tr>
<td>less<type>()</td>
<td>Binary</td>
<td>使用< </td>
</tr>
<tr>
<td>greater<type>()</td>
<td>Binary</td>
<td>使用> </td>
</tr>
<tr>
<td>less_equal<type>()</td>
<td>Binary</td>
<td>使用<= </td>
</tr>
<tr>
<td>greater_equal<type>()</td>
<td>Binary</td>
<td>使用>= </td>
</tr>
<tr>
<td>logical_not<type>()</td>
<td>Unary</td>
<td>使用!逻辑取反</td>
</tr>
<tr>
<td>logical_and<type>()</td>
<td>Binary</td>
<td>使用&#038;&#038;逻辑与</td>
</tr>
<tr>
<td>logical_or<type>()</td>
<td>Binary</td>
<td>使用||逻辑或</td>
</tr>
</table>
<h5>算术运算函数对象</h5>
<p>　　进行简单的算术运算，这类函数对象我用的很少，通常是自己定义。</p>
<table>
<caption>算术运算函数对象</caption>
<tr>
<th>函数对象</th>
<th>类型</th>
<th>描述</th>
</tr>
<tr>
<td>negate<type>()</td>
<td>Unary</td>
<td>使用-求负</td>
</tr>
<tr>
<td>plus<type>()</td>
<td>Binary</td>
<td>使用+加法</td>
</tr>
<tr>
<td>minus<type>()</td>
<td>Binary</td>
<td>使用-减法</td>
</tr>
<tr>
<td>multiplies<type>()</td>
<td>Binary</td>
<td>使用*乘法</td>
</tr>
<tr>
<td>divides<type>()</td>
<td>Binary</td>
<td>使用/除法</td>
</tr>
<tr>
<td>modulus<type>()</td>
<td>Binary</td>
<td>使用%求余</td>
</tr>
</table>
<h5>绑定Binders</h5>
<p>　　有两种绑定bind1st和bind2nd，它们可以将一个二元函数对象的其中一个参数绑定为某个已知的对象，从而得到一个一元函数对象。例如要在vector&lt;int&gt; v中查找等于372的值的位置，我可以将372绑定到equal_to&lt;int&gt;()的第一个或者第二个参数：</p>

<div class="wp_codebox"><table><tr id="p220916"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code" id="p2209code16"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">int</span>
main<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> argc, <span style="color: #0000ff;">char</span> <span style="color: #000040;">**</span>argv<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> v<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">1000</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        v.<span style="color: #007788;">push_back</span><span style="color: #008000;">&#40;</span>i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
    vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span><span style="color: #008080;">::</span><span style="color: #007788;">iterator</span> it<span style="color: #008080;">;</span>
    it <span style="color: #000080;">=</span> find_if<span style="color: #008000;">&#40;</span>v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, bind1st<span style="color: #008000;">&#40;</span>equal_to<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, <span style="color: #0000dd;">372</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span><span style="color: #000080;">&lt;&lt;</span><span style="color: #000040;">*</span>it<span style="color: #000080;">&lt;&lt;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>　　其实，这里的bind1st和bind2nd并不是函数对象，只是模板函数而已。这两个函数分别返回类型为binder1st和binder2nd的函数对象。下面的代码，聪明的你肯定一看就懂：</p>

<div class="wp_codebox"><table><tr id="p220917"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
</pre></td><td class="code" id="p2209code17"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// bind1st</span>
<span style="color: #0000ff;">template</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> Op<span style="color: #000080;">&gt;</span> 
<span style="color: #0000ff;">class</span> binder1st <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> unary_function
                  <span style="color: #000080;">&lt;</span><span style="color: #0000ff;">typename</span> Op<span style="color: #008080;">::</span><span style="color: #007788;">second_argument_type</span>,
                   <span style="color: #0000ff;">typename</span> Op<span style="color: #008080;">::</span><span style="color: #007788;">result_type</span><span style="color: #000080;">&gt;</span>
<span style="color: #008000;">&#123;</span>
   Op op_<span style="color: #008080;">;</span>
   <span style="color: #0000ff;">typename</span> Op<span style="color: #008080;">::</span><span style="color: #007788;">first_argument_type</span> first_arg_<span style="color: #008080;">;</span>
&nbsp;
   <span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
      binder1st<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> Op<span style="color: #000040;">&amp;</span> op,
                <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">typename</span> Op<span style="color: #008080;">::</span><span style="color: #007788;">first_argument_type</span><span style="color: #000040;">&amp;</span>
                first_arg<span style="color: #008000;">&#41;</span> <span style="color: #008080;">:</span> op_<span style="color: #008000;">&#40;</span>op<span style="color: #008000;">&#41;</span>,
               first_arg_<span style="color: #008000;">&#40;</span>first_arg<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
&nbsp;
   <span style="color: #0000ff;">typename</span> Op<span style="color: #008080;">::</span><span style="color: #007788;">result_type</span> operator<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
      <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">typename</span> Op<span style="color: #008080;">::</span><span style="color: #007788;">second_argument_type</span><span style="color: #000040;">&amp;</span> arg<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">const</span>
   <span style="color: #008000;">&#123;</span>
      <span style="color: #0000ff;">return</span> op_<span style="color: #008000;">&#40;</span>first_arg_, arg<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
   <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">template</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> Op, <span style="color: #0000ff;">class</span> Arg<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">inline</span> binder1st<span style="color: #000080;">&lt;</span>Op<span style="color: #000080;">&gt;</span> bind1st<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> Op<span style="color: #000040;">&amp;</span> op,
                             <span style="color: #0000ff;">const</span> Arg<span style="color: #000040;">&amp;</span> arg<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
   <span style="color: #0000ff;">return</span> binder1st<span style="color: #000080;">&lt;</span>Op<span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>op, arg<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #666666;">// bind2nd</span>
<span style="color: #0000ff;">template</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> Op<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">class</span> binder2nd <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> unary_function
   <span style="color: #000080;">&lt;</span><span style="color: #0000ff;">typename</span> Op<span style="color: #008080;">::</span><span style="color: #007788;">first_argument_type</span>,
    <span style="color: #0000ff;">typename</span> Op<span style="color: #008080;">::</span><span style="color: #007788;">result_type</span><span style="color: #000080;">&gt;</span>
<span style="color: #008000;">&#123;</span>
   Op op_<span style="color: #008080;">;</span>
   <span style="color: #0000ff;">typename</span> Op<span style="color: #008080;">::</span><span style="color: #007788;">second_argument_type</span> second_arg_<span style="color: #008080;">;</span>
&nbsp;
   <span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
      binder2nd<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> Op<span style="color: #000040;">&amp;</span> op,
                <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">typename</span> Op<span style="color: #008080;">::</span><span style="color: #007788;">second_argument_type</span><span style="color: #000040;">&amp;</span>
                                   second_arg<span style="color: #008000;">&#41;</span> <span style="color: #008080;">:</span> op_<span style="color: #008000;">&#40;</span>op<span style="color: #008000;">&#41;</span>,
                                   second_arg_<span style="color: #008000;">&#40;</span>second_arg<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
&nbsp;
   <span style="color: #0000ff;">typename</span> Op<span style="color: #008080;">::</span><span style="color: #007788;">result_type</span> operator<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> <span style="color: #0000ff;">typename</span>
      Op<span style="color: #008080;">::</span><span style="color: #007788;">argument_type</span><span style="color: #000040;">&amp;</span> arg<span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">const</span>
   <span style="color: #008000;">&#123;</span>
      <span style="color: #0000ff;">return</span> op_<span style="color: #008000;">&#40;</span>arg, second_arg_<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
   <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">template</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> Op, <span style="color: #0000ff;">class</span> Arg<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">inline</span> binder2nd<span style="color: #000080;">&lt;</span>Op<span style="color: #000080;">&gt;</span> bind2nd<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> Op<span style="color: #000040;">&amp;</span> op,
                             <span style="color: #0000ff;">const</span> Arg<span style="color: #000040;">&amp;</span> arg<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
   <span style="color: #0000ff;">return</span> binder2nd<span style="color: #000080;">&lt;</span>Op<span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span>op, arg<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<h5>Negaters</h5>
<p>　　Negater是针对Predicate设计的，它简单的将Predicate的返回值取反。有两个Negater，not1和not2，分别对一元和二元Predicate取反。</p>
<h5>Member Function Adapters</h5>
<p>　　有时候，你可能想让算法调用容器元素的成员函数，而不是外部函数。因为外部无法改变对象内的状态，且内部函数通常具有更高的效率。例如swap(string, string)总是没有string.swap(string)快速。又比如sort无法对list进行排序，这时候只能使用list.sort()来给链表排序。这时候就需要使用一定的方法将对象内部的函数“变成”函数对象，这样的函数对象叫做成员函数适配器，其实前面的binder也是一种适配器。看下面的例子：</p>

<div class="wp_codebox"><table><tr id="p220918"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
</pre></td><td class="code" id="p2209code18"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">int</span>
main<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> argc, <span style="color: #0000ff;">char</span> <span style="color: #000040;">**</span>argv<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    vector<span style="color: #000080;">&lt;</span>list<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> <span style="color: #000080;">&gt;</span> v<span style="color: #008080;">;</span>
    v.<span style="color: #007788;">push_back</span><span style="color: #008000;">&#40;</span>list<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    vector<span style="color: #000080;">&lt;</span>list<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> <span style="color: #000080;">&gt;</span><span style="color: #008080;">::</span><span style="color: #007788;">iterator</span> it<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span>it <span style="color: #000080;">=</span> v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> it <span style="color: #000040;">!</span><span style="color: #000080;">=</span> v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>it<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">20</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>it<span style="color: #008000;">&#41;</span>.<span style="color: #007788;">insert</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>it<span style="color: #008000;">&#41;</span>.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
    for_each<span style="color: #008000;">&#40;</span>v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>, std<span style="color: #008080;">::</span><span style="color: #007788;">mem_fun_ref</span><span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>list<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span><span style="color: #008080;">::</span><span style="color: #007788;">sort</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span>it <span style="color: #000080;">=</span> v.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> it <span style="color: #000040;">!</span><span style="color: #000080;">=</span> v.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>it<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span>list<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span><span style="color: #008080;">::</span><span style="color: #007788;">iterator</span> lt<span style="color: #008080;">;</span> lt <span style="color: #000040;">!</span><span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">*</span>it<span style="color: #008000;">&#41;</span>.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>lt<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span><span style="color: #000080;">&lt;&lt;</span><span style="color: #000040;">*</span>lt<span style="color: #000080;">&lt;&lt;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>上面的例子中，遍历vector&lt;list&lt;int&gt; &gt;并对链表进行排序。其中使用的是成员函数适配器mem_fun_ref，它返回的函数对象会以list&lt;int&gt;对象的引用为参数。另外一个mem_fun则是以指向list&lt;int&gt;对象的指针为参数。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2010/04/stl-functor-function-object/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[C++]exit &amp; abort &amp; 析构 &amp; 异常</title>
		<link>http://www.dutor.net/index.php/2010/04/exit-abort-des-except/</link>
		<comments>http://www.dutor.net/index.php/2010/04/exit-abort-des-except/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 12:20:46 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[OS基础]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=2187</guid>
		<description><![CDATA[<h4>进程之死</h4>
　　对于一个用C++写的程序，被加载至内存后运行，最终走向死亡。程序的死亡大致有三种：
<ul>
	<li><strong>自然死亡</strong>，即无疾而终，通常就是main()中的一个return 0;</li>
	<li><strong>自杀</strong>，当程序发现自己再活下去已经没有任何意义时，通常会选择自杀。当然，这种自杀也是一种请求式的自杀，即请求OS将自己毙掉。有两种方式：void exit(int status)和void abort(void)。</li>
	<li><strong>他杀</strong>，同现实不同的是，程序家族中的他杀行径往往是由自己至亲完成的，通常这个至亲就是他的生身父亲（还是母亲？）。C++并没有提供他杀的凶器，这些凶器往往是由OS直接或者间接（通过一些进程库，如pthread）提供的。</li>
</ul>
　　自然死是最完美的结局，他杀是我们最不愿意看到的，自杀虽是迫不得已，但主动权毕竟还是由程序自己掌控的。下面探究程序一下不同的死亡方式对对象的析构有何影响。]]></description>
			<content:encoded><![CDATA[<h4>进程之死</h4>
<p>　　对于一个用C++写的程序，被加载至内存后运行，最终走向死亡。程序的死亡大致有三种：</p>
<ul>
<li><strong>自然死亡</strong>，即无疾而终，通常就是main()中的一个return 0;</li>
<li><strong>自杀</strong>，当程序发现自己再活下去已经没有任何意义时，通常会选择自杀。当然，这种自杀也是一种请求式的自杀，即请求OS将自己毙掉。有两种方式：void exit(int status)和void abort(void)。</li>
<li><strong>他杀</strong>，同现实不同的是，程序家族中的他杀行径往往是由自己至亲完成的，通常这个至亲就是他的生身父亲（还是母亲？）。C++并没有提供他杀的凶器，这些凶器往往是由OS直接或者间接（通过一些进程库，如pthread）提供的。</li>
</ul>
<p>　　自然死是最完美的结局，他杀是我们最不愿意看到的，自杀虽是迫不得已，但主动权毕竟还是由程序自己掌控的。下面探究程序一下不同的死亡方式对对象的析构有何影响。</p>
<h4>程序死亡方式对对象析构的影响</h4>
<p>　　C++程序中大致有三种对象：全局对象、局部静态对象、局部非静态对象（自动对象）。举例说明之：</p>

<div class="wp_codebox"><table><tr id="p218719"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
</pre></td><td class="code" id="p2187code19"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">struct</span> Foo
<span style="color: #008000;">&#123;</span>
    Foo<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span><span style="color: #000080;">&lt;&lt;</span><span style="color: #FF0000;">&quot;Foo&quot;</span><span style="color: #000080;">&lt;&lt;</span>endl<span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>
    ~Foo<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span><span style="color: #000080;">&lt;&lt;</span><span style="color: #FF0000;">&quot;~Foo&quot;</span><span style="color: #000080;">&lt;&lt;</span>endl<span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #ff0000; font-style: italic;">/* some other sources here */</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
Foo Global<span style="color: #008080;">;</span>
<span style="color: #0000ff;">void</span> quit<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">int</span>
main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">static</span> Foo StaticLocal<span style="color: #008080;">;</span>
    Foo Local<span style="color: #008080;">;</span>
    <span style="color: #666666;">//~ quit();</span>
    <span style="color: #666666;">//~ abort();</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">void</span> quit<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    Foo AnotherLocal<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">exit</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>　　编译运行这个程序，程序将正常退出。运行过程中，Global对象在进入main之前首先被构造，其次是StaticLocal和Local。main函数退出之前，Local和StaticLocal被析构，main退出后Global也将被析构。<br />
　　如果将17行处quit()的注释去掉，我们将会看到4个对象被构造，但却只有两个对象被析构，分别是Global和StaticLocal对象，其他两个对象Local和AnotherLocal对象的析构函数将不会被调用。<br />
　　如果将18行处abort()的注释去掉（quit()被注释），3个对象对象被构造，但在程序退出之前没有任何一个对象的析构函数被调用。<br />
　　也就是说，正常情况下，所有类型的对象都将被析构；由exit退出时只有非自动对象被析构；abort被调用时，程序将直接退出，任何对象的析构函数都不会调用。下面着重介绍下exit的行为。</p>
<h4>exit做了什么</h4>
<p>　　介绍exit之前，不得不提void atexit(void (*f)(void) )函数。atexit，顾名思义，它描述了exit里面要做些什么。可以看出，它接受一个void f(void)形式的函数的指针。使用atexit我们可以向exit注册一些列的函数，这些函数在exit中被调用，调用的顺序与它们被注册的顺序相反。你可以使用下面的代码来验证：</p>

<div class="wp_codebox"><table><tr id="p218720"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code" id="p2187code20"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">void</span> f1<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span><span style="color: #000080;">&lt;&lt;</span><span style="color: #FF0000;">&quot;f1&quot;</span><span style="color: #000080;">&lt;&lt;</span>endl<span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">void</span> f2<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span><span style="color: #000080;">&lt;&lt;</span><span style="color: #FF0000;">&quot;f2&quot;</span><span style="color: #000080;">&lt;&lt;</span>endl<span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">int</span>
main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000dd;">atexit</span><span style="color: #008000;">&#40;</span>f1<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">atexit</span><span style="color: #008000;">&#40;</span>f2<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">exit</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>　　void exit(int status)被调用时，它首先调用全局的或者静态的对象的析构函数，然后调用atexit所注册的函数。如果这些函数中的某一个再次调用exit，your nightmare is coming。最后，exit会将代表程序执行状态的status<strong>“返回”</strong>（确切的说应该叫做传递，因为exit永远不会返回调用方）给当前程序的父进程。<br />
　　值得一提的是，执行exit结束程序，虽然自动对象的析构函数不被调用，但当程序结束时，OS会将该程序占用的资源全部释放。这些资源包括该程序申请的内存（堆）、打开的文件句柄、管道（Unix/Linux）、socket等。这样一来，似乎那些析构函数不被调用并不会有什么问题。确实，但可惜这只适用于单线程的程序。对于多线程程序来说，只有当整个进程结束时，它占用的资源才会被OS释放，这时某个线程的exit就可能带来麻烦（比如内存泄露）。怎么办呢？</p>
<h4>使用异常</h4>
<p>　　使用C++提供的异常机制，可以很好的解决上面提出的问题。我们可以在需要exit的地方抛出（throw）异常，然后在捕获（catch）异常处调用exit，这样，所有需要的析构函数都将被调用。代码通常是这个样子滴：</p>

<div class="wp_codebox"><table><tr id="p218721"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
</pre></td><td class="code" id="p2187code21"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;cstdlib&gt;</span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">struct</span> Foo
<span style="color: #008000;">&#123;</span>
    Foo<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span><span style="color: #000080;">&lt;&lt;</span><span style="color: #FF0000;">&quot;Foo&quot;</span><span style="color: #000080;">&lt;&lt;</span>endl<span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>
    ~Foo<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span><span style="color: #000080;">&lt;&lt;</span><span style="color: #FF0000;">&quot;~Foo&quot;</span><span style="color: #000080;">&lt;&lt;</span>endl<span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #ff0000; font-style: italic;">/* some other sources here */</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">struct</span> except<span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> exception
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">char</span><span style="color: #000040;">*</span> what<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">throw</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">return</span> <span style="color: #FF0000;">&quot;except&quot;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
Foo Global<span style="color: #008080;">;</span>
<span style="color: #0000ff;">void</span> quit<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">int</span>
main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">try</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">static</span> Foo StaticLocal<span style="color: #008080;">;</span>
        Foo Local<span style="color: #008080;">;</span>
        quit<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #0000ff;">catch</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> exception<span style="color: #000040;">&amp;</span> e<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000dd;">cerr</span><span style="color: #000080;">&lt;&lt;</span>e.<span style="color: #007788;">what</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #000080;">&lt;&lt;</span>endl<span style="color: #008080;">;</span>
        <span style="color: #0000dd;">exit</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">void</span> quit<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    Foo AnotherLocal<span style="color: #008080;">;</span>
    <span style="color: #666666;">//~ exit(1);</span>
    <span style="color: #0000ff;">throw</span> except<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>输出：</p>
<pre>
Foo
Foo
Foo
Foo
~Foo
~Foo
except
~Foo
~Foo
</pre>
<p><strong>补充：</strong>还有一个与atexit()相似的函数叫on_exit()，Google之。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2010/04/exit-abort-des-except/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[C++]覆盖std内的名字</title>
		<link>http://www.dutor.net/index.php/2010/04/name-look-up/</link>
		<comments>http://www.dutor.net/index.php/2010/04/name-look-up/#comments</comments>
		<pubDate>Tue, 20 Apr 2010 08:07:08 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[Cpp]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=2171</guid>
		<description><![CDATA[　　在现行的C++标准中有这么一个名字，std，它是一个namespace(命名空间)。C++标准库的所有类型/对象/函数/模板都定义在这个命名空间中。关于"What namespace? Why namespace? How namespace?" 的问题，任何一本基础的C++读物中都会有介绍，此处略过。为了使用std内定义的对象，可供使用的语法无非是
<pre lang="cpp" line="1">
std::vector<int> ivec;
//~ or
using std::vector;
vector<int> ivec;
//~ or
using namespace std;
vector<int> ivec;
</pre>
　　现在有这样一种需要，我想为std内的某种类型(比如string)重载操作符，而不想使用std内为我们提供的版本。]]></description>
			<content:encoded><![CDATA[<p>　　在现行的C++标准中有这么一个名字，std，它是一个namespace(命名空间)。C++标准库的所有类型/对象/函数/模板都定义在这个命名空间中。关于&#8221;What namespace? Why namespace? How namespace?&#8221; 的问题，任何一本基础的C++读物中都会有介绍，此处略过。为了使用std内定义的对象，可供使用的语法无非是</p>

<div class="wp_codebox"><table><tr id="p217122"><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code" id="p2171code22"><pre class="cpp" style="font-family:monospace;">std<span style="color: #008080;">::</span><span style="color: #007788;">vector</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> ivec<span style="color: #008080;">;</span>
<span style="color: #666666;">//~ or</span>
<span style="color: #0000ff;">using</span> std<span style="color: #008080;">::</span><span style="color: #007788;">vector</span><span style="color: #008080;">;</span>
vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> ivec<span style="color: #008080;">;</span>
<span style="color: #666666;">//~ or</span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
vector<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">int</span><span style="color: #000080;">&gt;</span> ivec<span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>　　现在有这样一种需要，我想为std内的某种类型(比如string)重载操作符，而不想使用std内为我们提供的版本。很简单：</p>

<div class="wp_codebox"><table><tr id="p217123"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code" id="p2171code23"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;string&gt;</span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
<span style="color: #0000ff;">bool</span> operator<span style="color: #000080;">&lt;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> string<span style="color: #000040;">&amp;</span> l, <span style="color: #0000ff;">const</span> string<span style="color: #000040;">&amp;</span> r<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">return</span> l <span style="color: #000080;">&gt;</span> r<span style="color: #008080;">;</span> <span style="color: #666666;">//~ 逆天而行了 :-)</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">int</span>
main<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> argc, <span style="color: #0000ff;">char</span> <span style="color: #000040;">**</span>argv<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000dd;">cout</span><span style="color: #000080;">&lt;&lt;</span>string<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;dutor&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #000080;">&lt;</span>string<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;ivan&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #000080;">&lt;&lt;</span>endl<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>　　运行这段代码，确实会得到我们想要的结果，dutor > ivan. 但是对于std内其他使用string的operator<()的对象还会这样吗？</p>

<div class="wp_codebox"><table><tr id="p217124"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code" id="p2171code24"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;string&gt;</span>
<span style="color: #339900;">#include &lt;set&gt;</span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
<span style="color: #0000ff;">bool</span> operator<span style="color: #000080;">&lt;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> string<span style="color: #000040;">&amp;</span> l, <span style="color: #0000ff;">const</span> string<span style="color: #000040;">&amp;</span> r<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">return</span> l <span style="color: #000080;">&gt;</span> r<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">int</span>
main<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> argc, <span style="color: #0000ff;">char</span> <span style="color: #000040;">**</span>argv<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    set<span style="color: #000080;">&lt;</span>string<span style="color: #000080;">&gt;</span> Set<span style="color: #008080;">;</span>
    Set.<span style="color: #007788;">insert</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;ivan&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    Set.<span style="color: #007788;">insert</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;dutor&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span>set<span style="color: #000080;">&lt;</span>string<span style="color: #000080;">&gt;</span><span style="color: #008080;">::</span><span style="color: #007788;">iterator</span> it <span style="color: #000080;">=</span> Set.<span style="color: #007788;">begin</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
            it <span style="color: #000040;">!</span><span style="color: #000080;">=</span> Set.<span style="color: #007788;">end</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>it<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000dd;">cout</span><span style="color: #000080;">&lt;&lt;</span><span style="color: #000040;">*</span>it<span style="color: #000080;">&lt;&lt;</span>endl<span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>　　这次ivan会在dutor前面输出吗？很遗憾，dutor被首先输出。不要忘了，std内还有一个operator<(const string&#038;, const string&#038;)呢！set调用的正是std里面的版本！那么我们有什么办法可以让set调用我们自己的operator<()呢？这涉及到C++的名字查找机制，C++采用的是一种懒惰的名字查找机制，也可以说是一种非贪婪式的查找。以本例来说，set与原始版本的operator<同属于std命名空间，set就会就近使用这个版本，而不是我们的自定义版本，而我们在main中使用的却是自定义版本。<br />
　　现在如何让set使用自定义的operator<已经变得明朗了，我们仅仅需要把我们的这个operator<添加到std中：</p>

<div class="wp_codebox"><table><tr id="p217125"><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code" id="p2171code25"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">namespace</span> std<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">bool</span> operator<span style="color: #000080;">&lt;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">const</span> string<span style="color: #000040;">&amp;</span> l, <span style="color: #0000ff;">const</span> string<span style="color: #000040;">&amp;</span> r<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">return</span> l <span style="color: #000080;">&gt;</span> r<span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>　　关于C++的名字查找机制，这里提到的只是皮毛而已，很多参考资料中到都做了深入的描述，请自行查阅。</p>
<p>　　刚才在当当买书，又看到雷人的一幕（我为什么说又？）：<br />
<a href="http://www.dutor.net/index.php/2010/04/name-look-up/stl1/" rel="attachment wp-att-2174"><img src="http://www.dutor.net/wp-content/uploads/2010/04/stl1.png" alt="" title="stl1" width="446" height="200" class="aligncenter size-full wp-image-2174" /></a><br />
<a href="http://www.dutor.net/index.php/2010/04/name-look-up/stl2/" rel="attachment wp-att-2175"><img src="http://www.dutor.net/wp-content/uploads/2010/04/stl2.png" alt="" title="stl2" width="480" height="222" class="aligncenter size-full wp-image-2175" /></a><br />
实在想不通，这￥0.56是哪里来的？</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2010/04/name-look-up/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Visual Studio中的Functional</title>
		<link>http://www.dutor.net/index.php/2010/04/visual-studio-functional/</link>
		<comments>http://www.dutor.net/index.php/2010/04/visual-studio-functional/#comments</comments>
		<pubDate>Sun, 18 Apr 2010 09:04:46 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[麻烦]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=2149</guid>
		<description><![CDATA[　　今天在VS中遇到一个十分诡异的事情，先看下面这个简单的程序：
<pre lang="cpp" line="1">
class cmp
{
public:
	bool operator()(long long l, long long r)
	{
		//~ 此间内容可略去不看。
		//~ 如果l和r含有的digits完全相同则返回false,
		//~ 如125 vs. 512
		char tmp1[1024], tmp2[1024];
		sprintf(tmp1,"%ld",l);
		sprintf(tmp2,"%ld",r);
		sort(tmp1, tmp1+strlen(tmp1));
		sort(tmp2, tmp2+strlen(tmp2));
		if (!strcmp(tmp1, tmp2))
		{
			return false;
		}
		return true;
	}
};
</pre>
]]></description>
			<content:encoded><![CDATA[<p>　　今天在VS中遇到一个十分诡异的事情，先看下面这个简单的程序：</p>

<div class="wp_codebox"><table><tr id="p214926"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
</pre></td><td class="code" id="p2149code26"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;set&gt;</span>
<span style="color: #339900;">#include &lt;algorithm&gt;</span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
<span style="color: #0000ff;">class</span> cmp
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
	<span style="color: #0000ff;">bool</span> operator<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">long</span> <span style="color: #0000ff;">long</span> l, <span style="color: #0000ff;">long</span> <span style="color: #0000ff;">long</span> r<span style="color: #008000;">&#41;</span>
	<span style="color: #008000;">&#123;</span>
		<span style="color: #666666;">//~ 此间内容可略去不看。</span>
		<span style="color: #666666;">//~ 如果l和r含有的digits完全相同则返回false,</span>
		<span style="color: #666666;">//~ 如125 vs. 512</span>
		<span style="color: #0000ff;">char</span> tmp1<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">1024</span><span style="color: #008000;">&#93;</span>, tmp2<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">1024</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
		<span style="color: #0000dd;">sprintf</span><span style="color: #008000;">&#40;</span>tmp1,<span style="color: #FF0000;">&quot;%ld&quot;</span>,l<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
		<span style="color: #0000dd;">sprintf</span><span style="color: #008000;">&#40;</span>tmp2,<span style="color: #FF0000;">&quot;%ld&quot;</span>,r<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
		sort<span style="color: #008000;">&#40;</span>tmp1, tmp1<span style="color: #000040;">+</span><span style="color: #0000dd;">strlen</span><span style="color: #008000;">&#40;</span>tmp1<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
		sort<span style="color: #008000;">&#40;</span>tmp2, tmp2<span style="color: #000040;">+</span><span style="color: #0000dd;">strlen</span><span style="color: #008000;">&#40;</span>tmp2<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
		<span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span><span style="color: #0000dd;">strcmp</span><span style="color: #008000;">&#40;</span>tmp1, tmp2<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
		<span style="color: #008000;">&#123;</span>
			<span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
		<span style="color: #008000;">&#125;</span>
		<span style="color: #0000ff;">return</span> <span style="color: #0000ff;">true</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> argc, <span style="color: #0000ff;">char</span><span style="color: #000040;">*</span> argv<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	set<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">long</span> <span style="color: #0000ff;">long</span>,cmp <span style="color: #000080;">&gt;</span> Set<span style="color: #008080;">;</span>
	<span style="color: #0000ff;">int</span> a<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">15</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
	Set.<span style="color: #007788;">insert</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	Set.<span style="color: #007788;">insert</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">2</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">//~ 此处疯狂</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>　　程序在这个地方跑偏了，弹出这么个东西</p>
<p><a href="http://www.dutor.net/index.php/2010/04/visual-studio-functional/vsnaocan/" rel="attachment wp-att-2150"><img src="http://www.dutor.net/wp-content/uploads/2010/04/vsnaocan.jpg" alt="" title="vsnaocan" width="377" height="244" class="aligncenter size-full wp-image-2150" /></a><br />
　　可是set的key_compare我一直都是这么用的啊。把程序拷到Linux下面用g++就一切正常。望达人指教。</p>
<h4>更新</h4>
<p>　　Johnny同学给的贴文中提到了，一个predicate对于任两个参数a,b不能返回<strong>两个true</strong>，即pred(a, b)和pred(b, a)不能同时返回true，这是strict weak规则决定的。代码为证：</p>

<div class="wp_codebox"><table><tr id="p214927"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code" id="p2149code27"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">template</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> _Pr, <span style="color: #0000ff;">class</span> _Ty1, <span style="color: #0000ff;">class</span> _Ty2<span style="color: #000080;">&gt;</span> <span style="color: #0000ff;">inline</span>
    <span style="color: #0000ff;">bool</span> __CLRCALL_OR_CDECL _Debug_lt_pred<span style="color: #008000;">&#40;</span>_Pr _Pred, _Ty1<span style="color: #000040;">&amp;</span> _Left, _Ty2<span style="color: #000040;">&amp;</span> _Right,
        <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">wchar_t</span> <span style="color: #000040;">*</span>_Where, <span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">int</span> _Line<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>    <span style="color: #666666;">// test if _Pred(_Left, _Right)  and _Pred is strict weak ordering</span>
    <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>_Pred <span style="color: #008000;">&#40;</span>_Left, _Right<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
        <span style="color: #0000ff;">return</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">false</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>_Pred<span style="color: #008000;">&#40;</span>_Right, _Left<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
        _DEBUG_ERROR2<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;invalid operator&lt;&quot;</span>, _Where, _Line<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">true</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>　　即是说，在调试时（特指Visual Studio的debug模式），bool _Debug_lt_pred()模板函数会对pred(a, b)的返回结果进行检查。如果pred(a, b)返回false没有问题。但如果其返回true，那么_Debug_lt_pred还会对pred(b, a)进行检查，若也返回true就会触发assert（有上图为证）。<br />
　　对于本文最初的代码，为了通过的_Debug_lt_pred的检查，我可以：</p>

<div class="wp_codebox"><table><tr id="p214928"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code" id="p2149code28"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">class</span> cmp
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
	<span style="color: #0000ff;">bool</span> operator<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">long</span> <span style="color: #0000ff;">long</span> l, <span style="color: #0000ff;">long</span> <span style="color: #0000ff;">long</span> r<span style="color: #008000;">&#41;</span>
	<span style="color: #008000;">&#123;</span>
		<span style="color: #666666;">//~ ……</span>
		<span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span><span style="color: #0000dd;">strcmp</span><span style="color: #008000;">&#40;</span>tmp1, tmp2<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
		<span style="color: #008000;">&#123;</span>
			<span style="color: #0000ff;">return</span> <span style="color: #0000ff;">false</span><span style="color: #008080;">;</span>
		<span style="color: #008000;">&#125;</span>
                <span style="color: #0000ff;">else</span>
		        <span style="color: #0000ff;">return</span> l <span style="color: #000080;">&lt;</span> r<span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>这样就保证了cmp::(long long, long long)不会返回<strong>&#8220;两个true&#8221;</strong>了</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2010/04/visual-studio-functional/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>[C++]优先级队列priority_queque</title>
		<link>http://www.dutor.net/index.php/2010/03/priority_queque/</link>
		<comments>http://www.dutor.net/index.php/2010/03/priority_queque/#comments</comments>
		<pubDate>Sat, 27 Mar 2010 11:15:59 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[STL]]></category>
		<category><![CDATA[算法]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=2096</guid>
		<description><![CDATA[　　好久没写C++没用STL了，今天在STLChina泡了一下午。完整的代码只写了这么一个，贴上来吧。
　　写了两个类，Max_Heap和Min_Heap，以他们特例化priority_queue，可以方便地实现最大、最小堆。写完了忽然又觉得这俩类似乎是多此一举了，完全可以用greater<int>来实现最小堆，但由priority_queue的模板定义看出，那样就必须提供一个容器类型，比如vector<int>。
　　最后还写了测试用例：找出ｎ个数中最大的k个。
<pre lang="cpp" line="1">
/*
template < class T, class Container = vector<T>,
           class Compare = less<typename Container::value_type> > class priority_queue;

explicit priority_queue ( const Compare&#038; x = Compare(),
                          const Container&#038; y = Container() );
template <class InputIterator>
         priority_queue ( InputIterator first, InputIterator last,
                          const Compare&#038; x = Compare(),
                          const Container&#038; y = Container() );
*/
</pre>]]></description>
			<content:encoded><![CDATA[<p>　　好久没写C++没用STL了，今天在STLChina泡了一下午。完整的代码只写了这么一个，贴上来吧。<br />
　　写了两个类，Max_Heap和Min_Heap，以他们特例化priority_queue，可以方便地实现最大、最小堆。写完了忽然又觉得这俩类似乎是多此一举了，完全可以用greater<int>来实现最小堆，但由priority_queue的模板定义看出，那样就必须提供一个容器类型，比如vector<int>。<br />
　　最后还写了测试用例：找出ｎ个数中最大的k个。</p>

<div class="wp_codebox"><table><tr id="p209629"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
</pre></td><td class="code" id="p2096code29"><pre class="cpp" style="font-family:monospace;"><span style="color: #ff0000; font-style: italic;">/*
template &lt; class T, class Container = vector&lt;T&gt;,
           class Compare = less&lt;typename Container::value_type&gt; &gt; class priority_queue;
&nbsp;
explicit priority_queue ( const Compare&amp; x = Compare(),
                          const Container&amp; y = Container() );
template &lt;class InputIterator&gt;
         priority_queue ( InputIterator first, InputIterator last,
                          const Compare&amp; x = Compare(),
                          const Container&amp; y = Container() );
*/</span>
<span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;queue&gt;</span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">struct</span> Max_Heap
<span style="color: #008000;">&#123;</span>
    Max_Heap<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span><span style="color: #008080;">:</span> _n<span style="color: #008000;">&#40;</span>n<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
    operator <span style="color: #0000ff;">int</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000ff;">return</span> _n<span style="color: #008080;">;</span><span style="color: #008000;">&#125;</span> <span style="color: #666666;">//在需要的地方隐式类型转换</span>
    <span style="color: #0000ff;">int</span> _n<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">struct</span> Min_Heap
<span style="color: #008000;">&#123;</span>
    Min_Heap<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span><span style="color: #008080;">:</span> _n<span style="color: #008000;">&#40;</span>n<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
    operator <span style="color: #0000ff;">int</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000ff;">return</span> _n<span style="color: #008080;">;</span><span style="color: #008000;">&#125;</span> <span style="color: #666666;">//在需要的地方隐式类型转换</span>
    <span style="color: #0000ff;">int</span> _n<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">bool</span> operator <span style="color: #000080;">&lt;</span> <span style="color: #008000;">&#40;</span>Max_Heap l, Max_Heap r<span style="color: #008000;">&#41;</span> <span style="color: #666666;">//~ 正常的&lt;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">return</span> l._n <span style="color: #000080;">&lt;</span> r._n<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">bool</span> operator <span style="color: #000080;">&lt;</span> <span style="color: #008000;">&#40;</span>Min_Heap l, Min_Heap r<span style="color: #008000;">&#41;</span> <span style="color: #666666;">//~ 反义的&lt;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">return</span> l._n <span style="color: #000080;">&gt;</span> r._n<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">int</span>
main <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> argc, <span style="color: #0000ff;">char</span> <span style="color: #000040;">**</span>argv<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    priority_queue<span style="color: #000080;">&lt;</span>Min_Heap<span style="color: #000080;">&gt;</span> heap<span style="color: #008080;">;</span> <span style="color: #666666;">//~ 最小堆</span>
    <span style="color: #666666;">//priority_queue&lt;Max_Heap&gt; heap; //~ 最大堆</span>
    <span style="color: #666666;">//~ 测试用例</span>
    <span style="color: #666666;">//~ 前K个最大值</span>
    <span style="color: #0000ff;">int</span> k <span style="color: #000080;">=</span> <span style="color: #0000dd;">5</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">int</span> tmp<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> k<span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000dd;">cin</span><span style="color: #000080;">&gt;&gt;</span>tmp<span style="color: #008080;">;</span>
        heap.<span style="color: #007788;">push</span><span style="color: #008000;">&#40;</span>tmp<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span><span style="color: #0000dd;">cin</span><span style="color: #000080;">&gt;&gt;</span>tmp<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>tmp <span style="color: #000080;">&gt;</span> heap.<span style="color: #007788;">top</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>._n<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            heap.<span style="color: #007788;">push</span><span style="color: #008000;">&#40;</span>tmp<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
            heap.<span style="color: #007788;">pop</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #0000dd;">cin</span>.<span style="color: #007788;">clear</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>heap.<span style="color: #007788;">size</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000dd;">cout</span><span style="color: #000080;">&lt;&lt;</span>heap.<span style="color: #007788;">top</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>._n<span style="color: #000080;">&lt;&lt;</span><span style="color: #FF0000;">' '</span><span style="color: #008080;">;</span>
        heap.<span style="color: #007788;">pop</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2010/03/priority_queque/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>一个关于大小端的问题</title>
		<link>http://www.dutor.net/index.php/2010/03/big-little-endian/</link>
		<comments>http://www.dutor.net/index.php/2010/03/big-little-endian/#comments</comments>
		<pubDate>Sun, 14 Mar 2010 09:14:59 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[大小端]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=2015</guid>
		<description><![CDATA[　　所谓大小端模式，就是一个关于数据字节在存储顺序的问题。在某些编程环境中，了解大小端是非常重要的，比如汇编和网络编程中，对存取和发送、接收数据的字节序都有严格的要求。当然，在高层次，你很少会需要考虑到这些。为什么会有大小端模式之分呢？这是因为在计算机系统中，我们是以字节为单位的，每个地址单元都对应着一个字节。在许多计算机语言中，许多数据类型都是多字节的，这就产生了多字节数据在内存中存放数据的问题。在大端模式（Big-endian）中，数据的低位（就是权值较小的后面那几位）保存在内存的高地址中，而数据的高位，保存在内存的低地址中；在小端模式（Little-endian）中，数据低位就存放在内存的低位。了解了什么是大小端，看下面的程序，输出结果是什么？
<pre lang="c" line="1">
#include <stdio.h>
int
main()
{
    int a[] = {1, 2, 3, 4, 5};
    int *ptr1 = (int*) (&#038;a + 1) - 1;
    int *ptr2 = (int*) ((int)a + 1);
    printf("%x, %x\n", *ptr1, *ptr2);
    return 0;
}
</pre>]]></description>
			<content:encoded><![CDATA[<p>　　所谓大小端模式，就是一个关于数据字节在存储顺序的问题。在某些编程环境中，了解大小端是非常重要的，比如汇编和网络编程中，对存取和发送、接收数据的字节序都有严格的要求。当然，在高层次，你很少会需要考虑到这些。为什么会有大小端模式之分呢？这是因为在计算机系统中，我们是以字节为单位的，每个地址单元都对应着一个字节。在许多计算机语言中，许多数据类型都是多字节的，这就产生了多字节数据在内存中存放数据的问题。在大端模式（Big-endian）中，数据的低位（就是权值较小的后面那几位）保存在内存的高地址中，而数据的高位，保存在内存的低地址中；在小端模式（Little-endian）中，数据低位就存放在内存的低位。了解了什么是大小端，看下面的程序，输出结果是什么？</p>

<div class="wp_codebox"><table><tr id="p201530"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code" id="p2015code30"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;stdio.h&gt;</span>
<span style="color: #993333;">int</span>
main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #993333;">int</span> a<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">3</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">4</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">5</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #993333;">int</span> <span style="color: #339933;">*</span>ptr1 <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>a <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
    <span style="color: #993333;">int</span> <span style="color: #339933;">*</span>ptr2 <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span><span style="color: #339933;">*</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">int</span><span style="color: #009900;">&#41;</span>a <span style="color: #339933;">+</span> <span style="color: #0000dd;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066;">printf</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;%x, %x<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #339933;">*</span>ptr1<span style="color: #339933;">,</span> <span style="color: #339933;">*</span>ptr2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>　　在我的机器上的输出时5, 2000000，可以看出是处理器是小端模式的。为什么呢？<br />
　　首先*ptr1 == 5是没有疑问的。<br />
　　再看看，*ptr2：</p>
<table>
<tr>
<td>内存编号</td>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>……</td>
</tr>
<tr>
<td>数据内容(16进制)</td>
<td>0&#215;01</td>
<td>0&#215;00</td>
<td>0&#215;00</td>
<td>0&#215;00</td>
<td>0&#215;02</td>
<td>……</td>
</tr>
</table>
<p>　　指针ptr2指向1号单元，因此*ptr2就是0&#215;02000000。在大端模式的机器中内存布局应该是这样滴：</p>
<table>
<tr>
<td>内存编号</td>
<td>0</td>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>……</td>
</tr>
<tr>
<td>数据内容(16进制)</td>
<td>0&#215;00</td>
<td>0&#215;00</td>
<td>0&#215;00</td>
<td>0&#215;01</td>
<td>0&#215;00</td>
<td>……</td>
</tr>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2010/03/big-little-endian/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>[C++]虚 静态函数</title>
		<link>http://www.dutor.net/index.php/2010/03/virtual-static-function/</link>
		<comments>http://www.dutor.net/index.php/2010/03/virtual-static-function/#comments</comments>
		<pubDate>Sat, 06 Mar 2010 10:44:28 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[Cpp]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=2012</guid>
		<description><![CDATA[　　C++类的静态函数是属于类型的，而不是某个对象的，因此把它声明成Virtual也没什么实际意义。那么运行下面这段程序，会产生什么样的结果呢？
<pre lang="cpp" line="1">
#include <iostream>
using namespace std;
class Base
{
public:
    static void foo() { cout<<"Base"<<endl; }
    virtual void bar() { foo(); }
};
</pre>]]></description>
			<content:encoded><![CDATA[<p>　　C++类的静态函数是属于类型的，而不是某个对象的，因此把它声明成Virtual也没什么实际意义。那么运行下面这段程序，会产生什么样的结果呢？</p>

<div class="wp_codebox"><table><tr id="p201231"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code" id="p2012code31"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
<span style="color: #0000ff;">class</span> Base
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> foo<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span><span style="color: #000080;">&lt;&lt;</span><span style="color: #FF0000;">&quot;Base&quot;</span><span style="color: #000080;">&lt;&lt;</span>endl<span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> bar<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> foo<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">class</span> Derived<span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> Base
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span> foo<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000dd;">cout</span><span style="color: #000080;">&lt;&lt;</span><span style="color: #FF0000;">&quot;Derived&quot;</span><span style="color: #000080;">&lt;&lt;</span>endl<span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>
    <span style="color: #0000ff;">virtual</span> <span style="color: #0000ff;">void</span> bar<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> foo<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">int</span> main
<span style="color: #008000;">&#123;</span>
    Base <span style="color: #000040;">*</span> p <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> Derived<span style="color: #008080;">;</span>
    p<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>bar<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000dd;">delete</span> p<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2010/03/virtual-static-function/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>[Tricks]C++成员函数和静态变量</title>
		<link>http://www.dutor.net/index.php/2010/02/cpp-fun-st/</link>
		<comments>http://www.dutor.net/index.php/2010/02/cpp-fun-st/#comments</comments>
		<pubDate>Sun, 21 Feb 2010 15:34:18 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[Cpp]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1989</guid>
		<description><![CDATA[　　想一下，下面的代码片段会输出什么？
<pre lang="cpp" line="1">
#include <iostream>
class Test
{
public:
    void print() const
    {
        std::cout<<_int<<std::endl;
    }
private:
    static int _int;
};
int Test::_int = 0;
int
main(int argc, char **argv)
{
    Test TArray[10];
    TArray[100].print();
    return 0;
}
</pre>
　　May you note something, anyhow.]]></description>
			<content:encoded><![CDATA[<p>　　想一下，下面的代码片段会输出什么？</p>

<div class="wp_codebox"><table><tr id="p198932"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td class="code" id="p1989code32"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #0000ff;">class</span> Test
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    <span style="color: #0000ff;">void</span> print<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">const</span>
    <span style="color: #008000;">&#123;</span>
        std<span style="color: #008080;">::</span><span style="color: #0000dd;">cout</span><span style="color: #000080;">&lt;&lt;</span>_int<span style="color: #000080;">&lt;&lt;</span>std<span style="color: #008080;">::</span><span style="color: #007788;">endl</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">private</span><span style="color: #008080;">:</span>
    <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">int</span> _int<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">int</span> Test<span style="color: #008080;">::</span>_int <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">int</span>
main<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> argc, <span style="color: #0000ff;">char</span> <span style="color: #000040;">**</span>argv<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    Test TArray<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">10</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
    TArray<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">100</span><span style="color: #008000;">&#93;</span>.<span style="color: #007788;">print</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>　　May you note something, anyhow.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2010/02/cpp-fun-st/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>char &amp; * &amp; []</title>
		<link>http://www.dutor.net/index.php/2009/11/char-pointer/</link>
		<comments>http://www.dutor.net/index.php/2009/11/char-pointer/#comments</comments>
		<pubDate>Sat, 28 Nov 2009 14:12:45 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[C]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1731</guid>
		<description><![CDATA[<pre lang="cpp" line="1">
void fun1(char * str) {}
void fun2(char ** str) {}

//~ int main(int argc, char ** argv)
int main(int argc, char * argv[])
{
	char str1[] = "Hello, Piggy!";
	char str2[][4] = "Hello, Piggy!";
	fun1(str1);
	fun2(str2);
	fun2(&#038;str1);
	return 0;
}
</pre>
　　上面的snippet有错误吗？有几个？你能找出来并说出原因吗？4、5两行有区别吗？想一下，然后看gcc给出的错误信息，]]></description>
			<content:encoded><![CDATA[
<div class="wp_codebox"><table><tr id="p173133"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code" id="p1731code33"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">void</span> fun1<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> str<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">void</span> fun2<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">char</span> <span style="color: #000040;">**</span> str<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #666666;">//~ int main(int argc, char ** argv)</span>
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> argc, <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> argv<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">char</span> str1<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #FF0000;">&quot;Hello, Piggy!&quot;</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">char</span> str2<span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span><span style="color: #008000;">&#91;</span><span style="color: #0000dd;">4</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #FF0000;">&quot;Hello, Piggy!&quot;</span><span style="color: #008080;">;</span>
	fun1<span style="color: #008000;">&#40;</span>str1<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	fun2<span style="color: #008000;">&#40;</span>str2<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	fun2<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>str1<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>　　上面的snippet有错误吗？有几个？你能找出来并说出原因吗？4、5两行有区别吗？想一下，然后看gcc给出的错误信息，</p>
<pre>
test.c: In function ‘main’:
test.c:9: error: invalid initializer
test.c:11: warning: passing argument 1 of ‘fun2’ from incompatible pointer type
test.c:4: note: expected ‘char **’ but argument is of type ‘char (*)[4]’
test.c:12: warning: passing argument 1 of ‘fun2’ from incompatible pointer type
test.c:4: note: expected ‘char **’ but argument is of type ‘char (*)[14]’
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/11/char-pointer/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>内存泄漏小陷阱</title>
		<link>http://www.dutor.net/index.php/2009/11/mem-leak-trap/</link>
		<comments>http://www.dutor.net/index.php/2009/11/mem-leak-trap/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 04:36:20 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[字符串]]></category>
		<category><![CDATA[汇编]]></category>
		<category><![CDATA[虚拟内存]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1681</guid>
		<description><![CDATA[<pre lang="cpp" line="1">
int
main()
{
	char * str = new char[32];
	str = "Hello, Piggy!";
	return 0;
}
</pre>
这样是会内存泄漏的……而我一直都不知道……不过想来也自然，因为这样是允许的，char *str = "Hello, Piggy!";，“程序中的字符串被存放在常量存储区”不要把这句话当成耳旁风，谨记。]]></description>
			<content:encoded><![CDATA[
<div class="wp_codebox"><table><tr id="p168134"><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code" id="p1681code34"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">int</span>
main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> str <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> <span style="color: #0000ff;">char</span><span style="color: #008000;">&#91;</span><span style="color: #0000dd;">32</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
	str <span style="color: #000080;">=</span> <span style="color: #FF0000;">&quot;Hello, Piggy!&quot;</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>这样是会内存泄漏的……而我一直都不知道……</p>

<div class="wp_codebox"><table><tr id="p168135"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="p1681code35"><pre class="asm" style="font-family:monospace;"><span style="color: #339933;">.</span>LC0<span style="color: #339933;">:</span>
	<span style="color: #339933;">.</span>string	<span style="color: #7f007f;">&quot;Hello, Piggy!&quot;</span>
	<span style="color: #339933;">.</span>text
<span style="color: #339933;">.</span>globl main
	<span style="color: #339933;">.</span><span style="color: #000000; font-weight: bold;">type</span>	main<span style="color: #339933;">,</span> @function
main<span style="color: #339933;">:</span>
	andl	$<span style="color: #339933;">-</span><span style="color: #0000ff;">16</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">esp</span>
	subl	$<span style="color: #0000ff;">32</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">esp</span>
	movl	$<span style="color: #0000ff;">32</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	<span style="color: #00007f; font-weight: bold;">call</span>	_Znaj
	movl	<span style="color: #339933;">%</span><span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">28</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	movl	$<span style="color: #339933;">.</span>LC0<span style="color: #339933;">,</span> <span style="color: #0000ff;">28</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span> <span style="color: #666666; font-style: italic;">;把str给覆盖了</span></pre></td></tr></table></div>

<p>不过想来也自然，因为这样是允许的，char *str = &#8220;Hello, Piggy!&#8221;;，“程序中的字符串被存放在常量存储区”不要把这句话当成耳旁风，谨记。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/11/mem-leak-trap/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>关于内联的疑问</title>
		<link>http://www.dutor.net/index.php/2009/11/about-inline/</link>
		<comments>http://www.dutor.net/index.php/2009/11/about-inline/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 23:35:12 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[内联]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1650</guid>
		<description><![CDATA[　　看<a href="http://chris.dutor.net/2009/11/10/%e6%9c%89%e5%85%b3%e5%86%85%e8%81%94%e5%87%bd%e6%95%b0%e7%9a%84%e4%b8%80%e4%ba%9b%e4%ba%8b/" target="_blank">Chris对内联的总结</a>，说到内联函数在编译时会被放入"符号表"，想一探究竟，结果却发现另外一个问题，疑惑不解。
<pre lang="cpp" line="1">
#include <stdio.h>
inline int add(int a, int b) { return a + b; }
int main()
{
	int n = add(1,2);
	return 0;
}
</pre>]]></description>
			<content:encoded><![CDATA[<p>　　看<a href="http://chris.dutor.net/2009/11/10/%e6%9c%89%e5%85%b3%e5%86%85%e8%81%94%e5%87%bd%e6%95%b0%e7%9a%84%e4%b8%80%e4%ba%9b%e4%ba%8b/" target="_blank">Chris对内联的总结</a>，说到内联函数在编译时会被放入&#8221;符号表&#8221;，想一探究竟，结果却发现另外一个问题，疑惑不解。</p>

<div class="wp_codebox"><table><tr id="p165036"><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code" id="p1650code36"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;stdio.h&gt;</span>
<span style="color: #0000ff;">inline</span> <span style="color: #0000ff;">int</span> add<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> a, <span style="color: #0000ff;">int</span> b<span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span> <span style="color: #0000ff;">return</span> a <span style="color: #000040;">+</span> b<span style="color: #008080;">;</span> <span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">int</span> n <span style="color: #000080;">=</span> add<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1</span>,<span style="color: #0000dd;">2</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>


<div class="wp_codebox"><table><tr id="p165037"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p1650code37"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">g++</span> <span style="color: #660033;">-otest</span> test.cpp
$ objdump .<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">test</span> <span style="color: #660033;">-d</span></pre></td></tr></table></div>


<div class="wp_codebox"><table><tr id="p165038"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre></td><td class="code" id="p1650code38"><pre class="asm" style="font-family:monospace;"><span style="color: #adadad; font-style: italic;">08048494</span> &lt;main&gt;<span style="color: #339933;">:</span>
 <span style="color: #0000ff;">8048494</span><span style="color: #339933;">:</span>	<span style="color: #0000ff;">55</span>                   	<span style="color: #00007f; font-weight: bold;">push</span>   <span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span>
 <span style="color: #0000ff;">8048495</span><span style="color: #339933;">:</span>	<span style="color: #0000ff;">89</span> e5                	<span style="color: #00007f; font-weight: bold;">mov</span>    <span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #339933;">,%</span><span style="color: #00007f;">ebp</span>
 <span style="color: #0000ff;">8048497</span><span style="color: #339933;">:</span>	<span style="color: #0000ff;">83</span> e4 f0             	<span style="color: #00007f; font-weight: bold;">and</span>    $<span style="color: #0000ff;">0xfffffff0</span><span style="color: #339933;">,%</span><span style="color: #00007f;">esp</span>
 804849a<span style="color: #339933;">:</span>	<span style="color: #0000ff;">83</span> ec <span style="color: #0000ff;">20</span>             	<span style="color: #00007f; font-weight: bold;">sub</span>    $<span style="color: #0000ff;">0x20</span><span style="color: #339933;">,%</span><span style="color: #00007f;">esp</span>
 804849d<span style="color: #339933;">:</span>	c7 <span style="color: #0000ff;">44</span> <span style="color: #0000ff;">24</span> <span style="color: #0000ff;">04</span> <span style="color: #0000ff;">02</span> <span style="color: #0000ff;">00</span> <span style="color: #0000ff;">00</span> 	movl   $<span style="color: #0000ff;">0x2</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0x4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
 80484a4<span style="color: #339933;">:</span>	<span style="color: #0000ff;">00</span> 
 80484a5<span style="color: #339933;">:</span>	c7 <span style="color: #0000ff;">04</span> <span style="color: #0000ff;">24</span> <span style="color: #0000ff;">01</span> <span style="color: #0000ff;">00</span> <span style="color: #0000ff;">00</span> <span style="color: #0000ff;">00</span> 	movl   $<span style="color: #0000ff;">0x1</span><span style="color: #339933;">,</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
 80484ac<span style="color: #339933;">:</span>	e8 <span style="color: #0000ff;">0b</span> <span style="color: #0000ff;">00</span> <span style="color: #0000ff;">00</span> <span style="color: #0000ff;">00</span>       	<span style="color: #00007f; font-weight: bold;">call</span>   80484bc &lt;_Z3addii&gt;
 80484b1<span style="color: #339933;">:</span>	<span style="color: #0000ff;">89</span> <span style="color: #0000ff;">44</span> <span style="color: #0000ff;">24</span> 1c          	<span style="color: #00007f; font-weight: bold;">mov</span>    <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span><span style="color: #339933;">,</span><span style="color: #0000ff;">0x1c</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
 80484b5<span style="color: #339933;">:</span>	b8 <span style="color: #0000ff;">00</span> <span style="color: #0000ff;">00</span> <span style="color: #0000ff;">00</span> <span style="color: #0000ff;">00</span>       	<span style="color: #00007f; font-weight: bold;">mov</span>    $<span style="color: #0000ff;">0x0</span><span style="color: #339933;">,%</span><span style="color: #00007f;">eax</span>
 80484ba<span style="color: #339933;">:</span>	c9                   	<span style="color: #00007f; font-weight: bold;">leave</span>  
 80484bb<span style="color: #339933;">:</span>	c3                   	<span style="color: #00007f; font-weight: bold;">ret</span>    
&nbsp;
<span style="color: #adadad; font-style: italic;">080484bc</span> &lt;_Z3addii&gt;<span style="color: #339933;">:</span>
 80484bc<span style="color: #339933;">:</span>	<span style="color: #0000ff;">55</span>                   	<span style="color: #00007f; font-weight: bold;">push</span>   <span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span>
 80484bd<span style="color: #339933;">:</span>	<span style="color: #0000ff;">89</span> e5                	<span style="color: #00007f; font-weight: bold;">mov</span>    <span style="color: #339933;">%</span><span style="color: #00007f;">esp</span><span style="color: #339933;">,%</span><span style="color: #00007f;">ebp</span>
 80484bf<span style="color: #339933;">:</span>	8b <span style="color: #0000ff;">45</span> 0c             	<span style="color: #00007f; font-weight: bold;">mov</span>    <span style="color: #0000ff;">0xc</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,%</span><span style="color: #00007f;">eax</span>
 80484c2<span style="color: #339933;">:</span>	8b <span style="color: #0000ff;">55</span> <span style="color: #0000ff;">08</span>             	<span style="color: #00007f; font-weight: bold;">mov</span>    <span style="color: #0000ff;">0x8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,%</span><span style="color: #00007f;">edx</span>
 80484c5<span style="color: #339933;">:</span>	8d <span style="color: #0000ff;">04</span> <span style="color: #0000ff;">02</span>             	<span style="color: #00007f; font-weight: bold;">lea</span>    <span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">edx</span><span style="color: #339933;">,%</span><span style="color: #00007f;">eax</span><span style="color: #339933;">,</span><span style="color: #0000ff;">1</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,%</span><span style="color: #00007f;">eax</span>
 80484c8<span style="color: #339933;">:</span>	5d                   	<span style="color: #00007f; font-weight: bold;">pop</span>    <span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span>
 80484c9<span style="color: #339933;">:</span>	c3                   	<span style="color: #00007f; font-weight: bold;">ret</span>    
 80484ca<span style="color: #339933;">:</span>	<span style="color: #0000ff;">90</span>                   	<span style="color: #00007f; font-weight: bold;">nop</span>
 80484cb<span style="color: #339933;">:</span>	<span style="color: #0000ff;">90</span>                   	<span style="color: #00007f; font-weight: bold;">nop</span></pre></td></tr></table></div>

<p>　　inline int add(int, int)没有内联，不解。另外，符号表里面也仅仅找到了_Z3addii，我不理解，干嘛把它放进符号表？我想这里的符号表不应该是熟知的那个符号表吧，应该只是编译期的一块用来inline的临时单元。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/11/about-inline/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Go！！！</title>
		<link>http://www.dutor.net/index.php/2009/11/go-program-lang/</link>
		<comments>http://www.dutor.net/index.php/2009/11/go-program-lang/#comments</comments>
		<pubDate>Thu, 12 Nov 2009 03:09:40 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[google]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1620</guid>
		<description><![CDATA[　　就在刚刚过去的2009年11月11日，举国欢庆的光棍节，Google推出了一个全新的系统编程语言<a href="http://golang.org/" target="_blank">Go Program Language</a>.  ……Simple……Fast……Safe……Concurrent……Funny……Open Source……似乎很牛B的样子，观望……期待……祝福]]></description>
			<content:encoded><![CDATA[<p>　　就在刚刚过去的2009年11月11日，举国欢庆的光棍节，Google推出了一个全新的系统编程语言<a href="http://golang.org/" target="_blank">Go Program Language</a>.  ……Simple……Fast……Safe……Concurrent……Funny……Open Source……似乎很牛B的样子，观望……期待……祝福</p>
<pre>
package main

import "fmt"

func main() {
  fmt.Printf("Hello, 世界\n")
}
</pre>
<p>Language Talk Show,<br />
<embed src="http://player.youku.com/player.php/sid/XMTMxMzIwMTQ4/v.swf" quality="high" width="480" height="400" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash"></embed></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/11/go-program-lang/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>C++模板为什么不能分离式编译</title>
		<link>http://www.dutor.net/index.php/2009/11/cpp-noisolate-compile/</link>
		<comments>http://www.dutor.net/index.php/2009/11/cpp-noisolate-compile/#comments</comments>
		<pubDate>Sat, 07 Nov 2009 13:44:21 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[模板]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1605</guid>
		<description><![CDATA[　　这里，编译main.cpp生成main.o时发现无法找到f到定义，就把它当作外部符号填入外部符号表，等待链接时确定其地址。而f(1); f(10); 通常是对应两条jmp 0x****h指令(当然还有参数的压栈操作)，0x****h地址处通常就是一条call f; (C++还会对f进行mangling处理)。这样链接器在链接main.o和test.o时，从test.o到导出符号表(或者内部符号表?)中找到f，得到对应的地址(每个符号对应一个偏移地址)，用这个地址替换f，再进行其他的一些必要的重定位，一个可执行文件就形成了。
　　说了这么多，那么C++模板为什么不能分离式编译呢？]]></description>
			<content:encoded><![CDATA[<p>　　对于多个C++编译单元，总是先编译器独立编译各个.cpp生成对应到目标文件.o或者.obj，然后再由链接器将各个目标文件进行链接从而得到最终的可执行文件(PE or ELF)。其实，.o和.obj和最终的可执行文件的格式已经是一样的了，只是其内部可能还有未解析的符号，而且地址也还是相对地址，链接时对未解析的外部符号进行地址替换，同时进行地址重定位，生成虚拟地址空间的可执行二进制代码文件。</p>

<div class="wp_codebox"><table><tr id="p160539"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code" id="p1605code39"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// test.h</span>
<span style="color: #0000ff;">void</span> f<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #666666;">// test.cpp</span>
<span style="color: #339900;">#include &quot;test.h&quot;</span>
<span style="color: #0000ff;">void</span> f<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> n<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #666666;">// do sthg.</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #666666;">// main.cpp</span>
<span style="color: #339900;">#include &quot;test.h&quot;</span>
<span style="color: #0000ff;">int</span>
main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	f<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	f<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">10</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>


<div class="wp_codebox"><table><tr id="p160540"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p1605code40"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">g++</span> test.cpp main.cpp <span style="color: #660033;">-c</span>
$ <span style="color: #c20cb9; font-weight: bold;">g++</span> test.o main.o <span style="color: #660033;">-o</span> main</pre></td></tr></table></div>

<p>　　这里，编译main.cpp生成main.o时发现无法找到f到定义，就把它当作外部符号填入外部符号表，等待链接时确定其地址。而f(1); f(10); 通常是对应两条jmp 0x****h指令(当然还有参数的压栈操作)，0x****h地址处通常就是一条call f; (C++还会对f进行mangling处理)。这样链接器在链接main.o和test.o时，从test.o到导出符号表(或者内部符号表?)中找到f，得到对应的地址(每个符号对应一个偏移地址)，用这个地址替换f，再进行其他的一些必要的重定位，一个可执行文件就形成了。<br />
　　说了这么多，那么C++模板为什么不能分离式编译呢？</p>

<div class="wp_codebox"><table><tr id="p160541"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code" id="p1605code41"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">// template.h</span>
<span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> T<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">void</span> f<span style="color: #008000;">&#40;</span>T t<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #666666;">// template.cpp</span>
<span style="color: #339900;">#include &quot;template.h&quot;</span>
<span style="color: #0000ff;">template</span> <span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> T<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">void</span> f<span style="color: #008000;">&#40;</span>T t<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #666666;">// do sthg.</span>
	T tt<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #666666;">// main.cpp</span>
<span style="color: #339900;">#include &quot;template.h&quot;</span>
<span style="color: #0000ff;">int</span>
main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	f<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">10</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	f<span style="color: #008000;">&#40;</span><span style="color:#800080;">1.0</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>


<div class="wp_codebox"><table><tr id="p160542"><td class="line_numbers"><pre>1
2
</pre></td><td class="code" id="p1605code42"><pre class="bash" style="font-family:monospace;">$ <span style="color: #c20cb9; font-weight: bold;">g++</span> template.cpp main.cpp <span style="color: #660033;">-c</span>
$ <span style="color: #c20cb9; font-weight: bold;">g++</span> template.o main.o <span style="color: #660033;">-o</span> main</pre></td></tr></table></div>

<p>　　这里，g++会提示：</p>
<pre>
main.o: In function `main':
main.cpp:(.text+0x11): undefined reference to `void f<int>(int)'
</pre>
<p>用</p>

<div class="wp_codebox"><table><tr id="p160543"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1605code43"><pre class="bash" style="font-family:monospace;">$ readelf template.o <span style="color: #660033;">-d</span></pre></td></tr></table></div>

<p>反汇编也没有任何输出，说明template.o的.text段中一行代码都没有生成。问题就在这里，因为只有当模板函数被调用时编译器才会其实例化，为其生成代码。又由于template.cpp是独立编译的，它看不到main.cpp对f<T>(T t)的调用，因此没有实例化的f<int>(int)代码生成。如果将template.cpp加入template.h，f(10)和f(1.0)就会分别被实例化为f<int>(int)和f<double>(double)，一切都恢复正常。</p>
<p>over~~~</p>
<p>？？？我写这些干吗？God knows.<br />
Bayes theorem 真的很牛B，很神奇。<br />
<img src="http://www.dutor.net/wp-content/cache/c8711a3977c45a8ecd2ae9a97f8ab94b.png" align="absmiddle" class="tex" alt="2 \pi r \to \pi r^2, en\,effect!?" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/11/cpp-noisolate-compile/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>sizeof只是个运算符</title>
		<link>http://www.dutor.net/index.php/2009/11/sizeof-just-operator/</link>
		<comments>http://www.dutor.net/index.php/2009/11/sizeof-just-operator/#comments</comments>
		<pubDate>Thu, 05 Nov 2009 04:35:05 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[汇编]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1595</guid>
		<description><![CDATA[　　有的东西，你自己觉得自己理解了知道了记住了，可能你真的记住了，但你真的理解了吗？Put a "Why" upon everything ever you touch. 
　　sizeof仅仅是个运算符，但那又意味着什么呢？意味着它不是一个函数，意味着它是在编译期求值(我并不是说所有的运算符都编译期求值)的。对于这样一条语句：
<pre lang="cpp" line="1">size_t size = sizeof(int);</pre>
来说，仅仅对应着这样一条汇编指令：
<pre lang="asm" line="1">movl	$4, -4(%ebp) </pre>
　　这对于自定义类型class也是同样的。]]></description>
			<content:encoded><![CDATA[<p>　　有的东西，你自己觉得自己理解了知道了记住了，可能你真的记住了，但你真的理解了吗？Put a &#8220;Why&#8221; upon everything ever you touch.<br />
　　sizeof仅仅是个运算符，但那又意味着什么呢？意味着它不是一个函数，意味着它是在编译期求值(我并不是说所有的运算符都编译期求值)的。对于这样一条语句：</p>

<div class="wp_codebox"><table><tr id="p159544"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1595code44"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">size_t</span> size <span style="color: #000080;">=</span> <span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>来说，仅仅对应着这样一条汇编指令：</p>

<div class="wp_codebox"><table><tr id="p159545"><td class="line_numbers"><pre>1
</pre></td><td class="code" id="p1595code45"><pre class="asm" style="font-family:monospace;">movl	$<span style="color: #0000ff;">4</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span></pre></td></tr></table></div>

<p>　　这对于自定义类型class也是同样的。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/11/sizeof-just-operator/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>一段小程序</title>
		<link>http://www.dutor.net/index.php/2009/11/snippets/</link>
		<comments>http://www.dutor.net/index.php/2009/11/snippets/#comments</comments>
		<pubDate>Tue, 03 Nov 2009 04:40:13 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[汇编]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1562</guid>
		<description><![CDATA[　　这里面猫腻儿还真不少。

　　karmic到源里面没有以前到vim-full包了，取而代之到是vim包，但现在有很多问题，n"+yy和n"+p无法和系统"剪切板"里到内容关联了，不知道什么原因。

<strong>Update</strong>
　　一切都释然了，只要意识到，>也需要进行类型提升。那么后面到-1啦-2啦之类的，都是很大很大的数了，循环根本就进不去，更别提死循环了。这样看来<strong>四、五</strong>两段程序就没有必要列出来了。其实，我是被它们的汇编代码给迷惑住了。]]></description>
			<content:encoded><![CDATA[<p><strong>一、</strong><br />
源程序，</p>

<div class="wp_codebox"><table><tr id="p156246"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code" id="p1562code46"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">int</span>
main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">unsigned</span> a <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">int</span> b <span style="color: #000080;">=</span> <span style="color: #0000dd;">1</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span>a <span style="color: #000040;">+</span> b <span style="color: #000080;">&gt;=</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">--</span>b<span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>汇编后，</p>

<div class="wp_codebox"><table><tr id="p156247"><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code" id="p1562code47"><pre class="asm" style="font-family:monospace;">	movl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	movl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
<span style="color: #339933;">.</span>L2<span style="color: #339933;">:</span>
	subl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	<span style="color: #00007f; font-weight: bold;">jmp</span>	<span style="color: #339933;">.</span>L2</pre></td></tr></table></div>

<p><strong>二、</strong><br />
源程序，</p>

<div class="wp_codebox"><table><tr id="p156248"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p1562code48"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">//...</span>
	<span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span>a <span style="color: #000040;">+</span> b <span style="color: #000080;">&gt;</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">--</span>b<span style="color: #008080;">;</span>
<span style="color: #666666;">//...</span></pre></td></tr></table></div>

<p>汇编后，</p>

<div class="wp_codebox"><table><tr id="p156249"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="p1562code49"><pre class="asm" style="font-family:monospace;">	movl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	movl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	<span style="color: #00007f; font-weight: bold;">jmp</span>	<span style="color: #339933;">.</span>L2
<span style="color: #339933;">.</span>L3<span style="color: #339933;">:</span>
	subl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
<span style="color: #339933;">.</span>L2<span style="color: #339933;">:</span>
	movl	<span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	addl	<span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	testl	<span style="color: #339933;">%</span><span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	<span style="color: #00007f; font-weight: bold;">setne</span>	<span style="color: #339933;">%</span><span style="color: #00007f;">al</span>
	testb	<span style="color: #339933;">%</span><span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">al</span>
	<span style="color: #00007f; font-weight: bold;">jne</span>	<span style="color: #339933;">.</span>L3</pre></td></tr></table></div>

<p><strong>三、</strong><br />
源程序，</p>

<div class="wp_codebox"><table><tr id="p156250"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p1562code50"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">//...</span>
	<span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span>a <span style="color: #000040;">+</span> b <span style="color: #000080;">&gt;</span> <span style="color: #000040;">-</span><span style="color: #0000dd;">2</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">--</span>b<span style="color: #008080;">;</span>
<span style="color: #666666;">//...</span></pre></td></tr></table></div>

<p>汇编后，</p>

<div class="wp_codebox"><table><tr id="p156251"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="p1562code51"><pre class="asm" style="font-family:monospace;">	movl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	movl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	<span style="color: #00007f; font-weight: bold;">jmp</span>	<span style="color: #339933;">.</span>L2
<span style="color: #339933;">.</span>L3<span style="color: #339933;">:</span>
	subl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
<span style="color: #339933;">.</span>L2<span style="color: #339933;">:</span>
	movl	<span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	addl	<span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	cmpl	$<span style="color: #339933;">-</span><span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	<span style="color: #00007f; font-weight: bold;">sete</span>	<span style="color: #339933;">%</span><span style="color: #00007f;">al</span>
	testb	<span style="color: #339933;">%</span><span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">al</span>
	<span style="color: #00007f; font-weight: bold;">jne</span>	<span style="color: #339933;">.</span>L3</pre></td></tr></table></div>

<p><strong>四、</strong><br />
源程序，</p>

<div class="wp_codebox"><table><tr id="p156252"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p1562code52"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">//...</span>
	<span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span>a <span style="color: #000040;">+</span> b <span style="color: #000080;">&gt;=</span> <span style="color: #000040;">-</span><span style="color: #0000dd;">2</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">--</span>b<span style="color: #008080;">;</span>
<span style="color: #666666;">//...</span></pre></td></tr></table></div>

<p>汇编后，</p>

<div class="wp_codebox"><table><tr id="p156253"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="p1562code53"><pre class="asm" style="font-family:monospace;">	movl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	movl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	<span style="color: #00007f; font-weight: bold;">jmp</span>	<span style="color: #339933;">.</span>L2
<span style="color: #339933;">.</span>L3<span style="color: #339933;">:</span>
	subl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
<span style="color: #339933;">.</span>L2<span style="color: #339933;">:</span>
	movl	<span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	addl	<span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	cmpl	$<span style="color: #339933;">-</span><span style="color: #0000ff;">3</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	<span style="color: #00007f; font-weight: bold;">seta</span>	<span style="color: #339933;">%</span><span style="color: #00007f;">al</span>
	testb	<span style="color: #339933;">%</span><span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">al</span>
	<span style="color: #00007f; font-weight: bold;">jne</span>	<span style="color: #339933;">.</span>L3</pre></td></tr></table></div>

<p><strong>五、</strong><br />
源代码，</p>

<div class="wp_codebox"><table><tr id="p156254"><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code" id="p1562code54"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">//...</span>
	<span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span>a <span style="color: #000040;">+</span> b <span style="color: #000080;">&gt;=</span> <span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span> <span style="color: #000040;">--</span>b<span style="color: #008080;">;</span>
<span style="color: #666666;">//...</span></pre></td></tr></table></div>

<p>汇编后，</p>

<div class="wp_codebox"><table><tr id="p156255"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code" id="p1562code55"><pre class="asm" style="font-family:monospace;">	movl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	movl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
	<span style="color: #00007f; font-weight: bold;">jmp</span>	<span style="color: #339933;">.</span>L2
<span style="color: #339933;">.</span>L3<span style="color: #339933;">:</span>
	subl	$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span>
<span style="color: #339933;">.</span>L2<span style="color: #339933;">:</span>
	movl	<span style="color: #339933;">-</span><span style="color: #0000ff;">8</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	addl	<span style="color: #339933;">-</span><span style="color: #0000ff;">4</span><span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span><span style="color: #00007f;">ebp</span><span style="color: #009900; font-weight: bold;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	testl	<span style="color: #339933;">%</span><span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span>
	<span style="color: #00007f; font-weight: bold;">setne</span>	<span style="color: #339933;">%</span><span style="color: #00007f;">al</span>
	testb	<span style="color: #339933;">%</span><span style="color: #00007f;">al</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">al</span>
	<span style="color: #00007f; font-weight: bold;">jne</span>	<span style="color: #339933;">.</span>L3</pre></td></tr></table></div>

<p>　　<br />
　　这里面猫腻儿还真不少。</p>
<p>　　karmic到源里面没有以前到vim-full包了，取而代之到是vim包，但现在有很多问题，n&#8221;+yy和n&#8221;+p无法和系统&#8221;剪切板&#8221;里到内容关联了，不知道什么原因。</p>
<p><strong>Update</strong><br />
　　一切都释然了，只要意识到，>也需要进行类型提升。那么后面到-1啦-2啦之类的，都是很大很大的数了，循环根本就进不去，更别提死循环了。这样看来<strong>四、五</strong>两段程序就没有必要列出来了。其实，我是被它们的汇编代码给迷惑住了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/11/snippets/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>还是虚存</title>
		<link>http://www.dutor.net/index.php/2009/11/vm-again/</link>
		<comments>http://www.dutor.net/index.php/2009/11/vm-again/#comments</comments>
		<pubDate>Sun, 01 Nov 2009 08:14:09 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[Unix/Linux]]></category>
		<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[OS基础]]></category>
		<category><![CDATA[虚拟内存]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1541</guid>
		<description><![CDATA[　　只占了十分之一左右！这又是为什么呢？永远也学不完的虚拟内存啊！

　　呃……又SB了！const int size = 2^30;这哪里是1G啊！分明是28嘛！Orz...汇编码里面尽是28！这下好了，改成1<<30，运行了四个实例，机器就笨的像猪了：

　　等程序结束了，刚开始运行着到浏览器也慢了一会儿，估计是被换到交换文件里面去了。]]></description>
			<content:encoded><![CDATA[<p>　　看这个简单的程序：</p>

<div class="wp_codebox"><table><tr id="p154156"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code" id="p1541code56"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
<span style="color: #0000ff;">int</span>
main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">const</span> <span style="color: #0000ff;">int</span> size <span style="color: #000080;">=</span> <span style="color: #0000dd;">2</span><span style="color: #000040;">^</span><span style="color: #0000dd;">30</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span> p <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> <span style="color: #0000ff;">char</span><span style="color: #008000;">&#91;</span>size<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> size<span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        p<span style="color: #008000;">&#91;</span>i<span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
    sleep<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">121</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>　　在后台运行该程序的多个实例，并查看内存占用：</p>

<div class="wp_codebox"><table><tr id="p154157"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code" id="p1541code57"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">&#91;</span>04:07 PM<span style="color: #7a0874; font-weight: bold;">&#93;</span> ivan<span style="color: #000000; font-weight: bold;">@</span>ivan-desktop ~<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">cpp</span><span style="color: #000000; font-weight: bold;">&gt;</span> .<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">test</span><span style="color: #000000; font-weight: bold;">&amp;</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000;">8345</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>04:07 PM<span style="color: #7a0874; font-weight: bold;">&#93;</span> ivan<span style="color: #000000; font-weight: bold;">@</span>ivan-desktop ~<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">cpp</span><span style="color: #000000; font-weight: bold;">&gt;</span> .<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">test</span><span style="color: #000000; font-weight: bold;">&amp;</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">2</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000;">8346</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>04:07 PM<span style="color: #7a0874; font-weight: bold;">&#93;</span> ivan<span style="color: #000000; font-weight: bold;">@</span>ivan-desktop ~<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">cpp</span><span style="color: #000000; font-weight: bold;">&gt;</span> .<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">test</span><span style="color: #000000; font-weight: bold;">&amp;</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">3</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000;">8347</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>04:07 PM<span style="color: #7a0874; font-weight: bold;">&#93;</span> ivan<span style="color: #000000; font-weight: bold;">@</span>ivan-desktop ~<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">cpp</span><span style="color: #000000; font-weight: bold;">&gt;</span> .<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">test</span><span style="color: #000000; font-weight: bold;">&amp;</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">4</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000;">8348</span>
<span style="color: #7a0874; font-weight: bold;">&#91;</span>04:07 PM<span style="color: #7a0874; font-weight: bold;">&#93;</span> ivan<span style="color: #000000; font-weight: bold;">@</span>ivan-desktop ~<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">cpp</span><span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #c20cb9; font-weight: bold;">free</span></pre></td></tr></table></div>

<pre>
             total       used       free     shared    buffers     cached
Mem:       1997172    1942672      54500          0     486080    1067476
</pre>
<p>　　只占了十分之一左右！这又是为什么呢？永远也学不完的虚拟内存啊！</p>
<p>　　呃……又SB了！const int size = 2^30;这哪里是1G啊！分明是28嘛！Orz&#8230;汇编码里面尽是28！这下好了，改成1<<30，运行了四个实例，机器就笨的像猪了：<br />
<div class="wp-caption aligncenter" style="width: 626px"><img alt="System Monitor" src="http://www.dutor.net/files/images/vaalloc.png" title="System Monitor" width="616" height="523" /><p class="wp-caption-text">System Monitor</p></div></p>
<p>　　等程序结束了，刚开始运行着到浏览器也慢了一会儿，估计是被换到交换文件里面去了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/11/vm-again/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>fstream二进制形式读取文件</title>
		<link>http://www.dutor.net/index.php/2009/09/fstream-ios-binary/</link>
		<comments>http://www.dutor.net/index.php/2009/09/fstream-ios-binary/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 02:16:26 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[OS基础]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1372</guid>
		<description><![CDATA[我试图以二进制的方式打开文件movie.avi，并复制到另外一个文件film.avi，于是写了下面的一段代码。问题是，这段代码只对某些文件适用，而无法"完全"复制另外一些文件，也就是说，当源文件并没有读完时却已经提前结束了。我想应该是某一个特殊字节的值导致read认为文件已经读完了，但我是以二进制方式打开的文件呀，这种情况下，文件结束符EOF还有意义吗？puzzling……]]></description>
			<content:encoded><![CDATA[<p>我试图以二进制的方式打开文件movie.avi，并复制到另外一个文件film.avi，于是写了下面的一段代码。问题是，这段代码只对某些文件适用，而无法&#8221;完全&#8221;复制另外一些文件，也就是说，当源文件并没有读完时却已经提前结束了。我想应该是某一个特殊字节的值导致read认为文件已经读完了，但我是以二进制方式打开的文件呀，这种情况下，文件结束符EOF还有意义吗？puzzling……</p>

<div class="wp_codebox"><table><tr id="p137258"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code" id="p1372code58"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">int</span>
main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">char</span> buf<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">4096</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
    ofstream out<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;film.avi&quot;</span> <span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    ifstream in<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;movie.avi&quot;</span>, ios<span style="color: #008080;">::</span><span style="color: #007788;">binary</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #666666;">// ifstream in(&quot;movie.rmvb&quot;);</span>
    <span style="color: #0000ff;">while</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        in.<span style="color: #007788;">read</span><span style="color: #008000;">&#40;</span>buf, <span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span>buf<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        out.<span style="color: #007788;">write</span><span style="color: #008000;">&#40;</span>buf, in.<span style="color: #007788;">gcount</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">if</span><span style="color: #008000;">&#40;</span>in.<span style="color: #007788;">gcount</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span>buf<span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span> <span style="color: #0000ff;">break</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
    in.<span style="color: #007788;">close</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    out.<span style="color: #007788;">close</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/09/fstream-ios-binary/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>线程消息队列</title>
		<link>http://www.dutor.net/index.php/2009/08/thread-queue/</link>
		<comments>http://www.dutor.net/index.php/2009/08/thread-queue/#comments</comments>
		<pubDate>Sat, 22 Aug 2009 10:09:54 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[Unix/Linux]]></category>
		<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[pthread]]></category>
		<category><![CDATA[多线程]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1150</guid>
		<description><![CDATA[<ol>
	<li>减少pthread_cond_signal和sem_post的调用，只在有必要的时候调用；</li>
	<li>尽量避免pthread_mutex进入竞争态。增大消息队列的大小，可以有效减少竞态条件的出现。</li>
</ol>
      /*
       * 此处循环判断的原因如下：假设2个线程在getq阻塞，然后两者都被激活，
       * 而其中一个线程运行比较块，快速消耗了2个数据，
       * 另一个线程醒来的时候已经没有新数据可以消耗了。
       * 另一点，man pthread_cond_wait可以看到，
       * 该函数可以被信号中断返回，此时返回EINTR。
       * 为避免以上任何一点，都必须醒来后再次判断睡眠条件。
       * 更正：pthread_cond_wait是信号安全的系统调用，不会被信号中断。
       */]]></description>
			<content:encoded><![CDATA[<ol>
<li>减少pthread_cond_signal和sem_post的调用，只在有必要的时候调用；</li>
<li>尽量避免pthread_mutex进入竞争态。增大消息队列的大小，可以有效减少竞态条件的出现。</li>
</ol>

<div class="wp_codebox"><table><tr id="p115059"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
</pre></td><td class="code" id="p1150code59"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;pthread.h&gt;</span>
<span style="color: #0000ff;">class</span> CThreadQueue
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
    CThreadQueue <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> queueSize <span style="color: #000080;">=</span> <span style="color: #0000dd;">1024</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">:</span>
  sizeQueue <span style="color: #008000;">&#40;</span>queueSize<span style="color: #008000;">&#41;</span>, lput <span style="color: #008000;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span>, lget <span style="color: #008000;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span>, nFullThread <span style="color: #008000;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span>,
      nEmptyThread <span style="color: #008000;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span>, nData <span style="color: #008000;">&#40;</span><span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
      pthread_mutex_init <span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>mux, <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
      pthread_cond_init <span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>condGet, <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
      pthread_cond_init <span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>condPut, <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
      buffer <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> <span style="color: #0000ff;">void</span> <span style="color: #000040;">*</span><span style="color: #008000;">&#91;</span>sizeQueue<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
  <span style="color: #0000ff;">virtual</span> ~ CThreadQueue <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
      pthread_mutex_destroy <span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>mux<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
      pthread_cond_destroy <span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>condGet<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
      pthread_cond_destroy <span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>condPut<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
      <span style="color: #0000dd;">delete</span><span style="color: #008000;">&#91;</span><span style="color: #008000;">&#93;</span>buffer<span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
  <span style="color: #0000ff;">void</span> <span style="color: #000040;">*</span>getq <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
      <span style="color: #0000ff;">void</span> <span style="color: #000040;">*</span>data<span style="color: #008080;">;</span>
      pthread_mutex_lock <span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>mux<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
      <span style="color: #ff0000; font-style: italic;">/*
       * 此处循环判断的原因如下：假设2个线程在getq阻塞，然后两者都被激活，
       * 而其中一个线程运行比较块，快速消耗了2个数据，
       * 另一个线程醒来的时候已经没有新数据可以消耗了。
       * 另一点，man pthread_cond_wait可以看到，
       * 该函数可以被信号中断返回，此时返回EINTR。
       * 为避免以上任何一点，都必须醒来后再次判断睡眠条件。
       * 更正：pthread_cond_wait是信号安全的系统调用，不会被信号中断。
       */</span>
      <span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>lget <span style="color: #000080;">==</span> lput <span style="color: #000040;">&amp;&amp;</span> nData <span style="color: #000080;">==</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span>
      <span style="color: #008000;">&#123;</span>
        nEmptyThread<span style="color: #000040;">++</span><span style="color: #008080;">;</span>
        pthread_cond_wait <span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>condGet, <span style="color: #000040;">&amp;</span>mux<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        nEmptyThread<span style="color: #000040;">--</span><span style="color: #008080;">;</span>
      <span style="color: #008000;">&#125;</span>
&nbsp;
      data <span style="color: #000080;">=</span> buffer<span style="color: #008000;">&#91;</span>lget<span style="color: #000040;">++</span><span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
      nData<span style="color: #000040;">--</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>lget <span style="color: #000080;">==</span> sizeQueue<span style="color: #008000;">&#41;</span>
      <span style="color: #008000;">&#123;</span>
        lget <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
      <span style="color: #008000;">&#125;</span>
      <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>nFullThread<span style="color: #008000;">&#41;</span>                  <span style="color: #666666;">//必要时才进行signal操作，勿总是signal</span>
      <span style="color: #008000;">&#123;</span>
        pthread_cond_signal <span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>condPut<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
      <span style="color: #008000;">&#125;</span>
      pthread_mutex_unlock <span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>mux<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">return</span> data<span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
  <span style="color: #0000ff;">void</span> putq <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span> <span style="color: #000040;">*</span>data<span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
      pthread_mutex_lock <span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>mux<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>lput <span style="color: #000080;">==</span> lget <span style="color: #000040;">&amp;&amp;</span> nData<span style="color: #008000;">&#41;</span>
      <span style="color: #008000;">&#123;</span>
        nFullThread<span style="color: #000040;">++</span><span style="color: #008080;">;</span>
        pthread_cond_wait <span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>condPut, <span style="color: #000040;">&amp;</span>mux<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        nFullThread<span style="color: #000040;">--</span><span style="color: #008080;">;</span>
      <span style="color: #008000;">&#125;</span>
      buffer<span style="color: #008000;">&#91;</span>lput<span style="color: #000040;">++</span><span style="color: #008000;">&#93;</span> <span style="color: #000080;">=</span> data<span style="color: #008080;">;</span>
      nData<span style="color: #000040;">++</span><span style="color: #008080;">;</span>
      <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>lput <span style="color: #000080;">==</span> sizeQueue<span style="color: #008000;">&#41;</span>
      <span style="color: #008000;">&#123;</span>
        lput <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
      <span style="color: #008000;">&#125;</span>
      <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>nEmptyThread<span style="color: #008000;">&#41;</span>
      <span style="color: #008000;">&#123;</span>
        pthread_cond_signal <span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>condGet<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
      <span style="color: #008000;">&#125;</span>
      pthread_mutex_unlock <span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>mux<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">private</span><span style="color: #008080;">:</span>
  pthread_mutex_t mux<span style="color: #008080;">;</span>
  pthread_cond_t condGet<span style="color: #008080;">;</span>
  pthread_cond_t condPut<span style="color: #008080;">;</span>
&nbsp;
  <span style="color: #0000ff;">void</span> <span style="color: #000040;">**</span>buffer<span style="color: #008080;">;</span>                        <span style="color: #666666;">//循环消息队列</span>
  <span style="color: #0000ff;">int</span> sizeQueue<span style="color: #008080;">;</span>                        <span style="color: #666666;">//队列大小</span>
  <span style="color: #0000ff;">int</span> lput<span style="color: #008080;">;</span>                                    <span style="color: #666666;">//location put  放数据的指针偏移</span>
  <span style="color: #0000ff;">int</span> lget<span style="color: #008080;">;</span>                                    <span style="color: #666666;">//location get  取数据的指针偏移</span>
  <span style="color: #0000ff;">int</span> nFullThread<span style="color: #008080;">;</span>                        <span style="color: #666666;">//队列满，阻塞在putq处的线程数</span>
  <span style="color: #0000ff;">int</span> nEmptyThread<span style="color: #008080;">;</span>                        <span style="color: #666666;">//队列空，阻塞在getq处的线程数</span>
  <span style="color: #0000ff;">int</span> nData<span style="color: #008080;">;</span>                              <span style="color: #666666;">//队列中的消息个数，主要用来判断队列空还是满</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #666666;">//使用的时候给出稍大的CThreadQueue初始化参数，可以减少进入内核态的操作。</span>
CThreadQueue queue<span style="color: #008080;">;</span>
<span style="color: #0000ff;">void</span> <span style="color: #000040;">*</span>
produce <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span> <span style="color: #000040;">*</span>arg<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
  <span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
  pthread_detach <span style="color: #008000;">&#40;</span>pthread_self <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>i<span style="color: #000040;">++</span> <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">100</span><span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
      queue.<span style="color: #007788;">putq</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span> <span style="color: #000040;">*</span><span style="color: #008000;">&#41;</span> i<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">void</span> <span style="color: #000040;">*</span>
consume <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span> <span style="color: #000040;">*</span>arg<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
  <span style="color: #0000ff;">int</span> data<span style="color: #008080;">;</span>
  <span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span>
  <span style="color: #008000;">&#123;</span>
      data <span style="color: #000080;">=</span> <span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#40;</span>queue.<span style="color: #007788;">getq</span> <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
      <span style="color: #0000dd;">printf</span> <span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;data=%d<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span>, data<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">int</span>
main <span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
  pthread_t pid<span style="color: #008080;">;</span>
  <span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
&nbsp;
  <span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>i<span style="color: #000040;">++</span> <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">3</span><span style="color: #008000;">&#41;</span>
      pthread_create <span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>pid, <span style="color: #0000dd;">0</span>, produce, <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
  <span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span>i<span style="color: #000040;">++</span> <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">3</span><span style="color: #008000;">&#41;</span>
      pthread_create <span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>pid, <span style="color: #0000dd;">0</span>, consume, <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  sleep <span style="color: #008000;">&#40;</span><span style="color: #0000dd;">30</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/08/thread-queue/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>还是delete</title>
		<link>http://www.dutor.net/index.php/2009/08/delete-ag/</link>
		<comments>http://www.dutor.net/index.php/2009/08/delete-ag/#comments</comments>
		<pubDate>Sat, 22 Aug 2009 02:35:10 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[delete]]></category>
		<category><![CDATA[虚拟内存]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1141</guid>
		<description><![CDATA[表明看来似乎合情合理，由于C++的多态特性，允许我们将一个子类地址赋给父类型的指针pb，释放对象时理所当然的对pb进行delete。但，在程序运行时，并没有输出M destructed...，即D::m的析构函数没有被调用，而m的析构函数是需要D::~D()来调用的，所以子类D的析构函数也没有被调用。这是很容易理解的，因为父类的析构函数不是virtual的。由此，我们得出结论，用来继承的父类的析构函数总应该是virtual的，除非你确定它绝对不会被用于多态。关于这一点，《Effective C++》里面已经讲到了。

除了上面的问题，我们还应该关心的是，尽管析构函数没有被调用，那M::i的空间被释放了吗？It's a question！由于析构函数没有被调用，那么释放M::i的任务就完全落在了delete身上的了，那么delete做到了吗？It's a very question！这又回到了<a href="http://www.dutor.net/index.php/2009/08/free-delete/" target="_blank">上一篇日志</a>中所描述的问题上了。我的观点是delete做到了它应该做的事情，它只负责释放当初new申请的空间，即对象<strong>本身</strong>，至于对象里面是否有动态申请的内存，那就不是delete而是对象析构函数自己的工作了。]]></description>
			<content:encoded><![CDATA[<p>以前写过一篇<a href="http://www.dutor.net/index.php/2009/08/free-delete/" target="_blank">关于delete</a>的日志，那里提到的只是一个实验而已，我想正常人不会犯那么弱智的错误吧。但接下来的这个问题就不得不加倍留心了。直接看代码：</p>

<div class="wp_codebox"><table><tr id="p114160"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
</pre></td><td class="code" id="p1141code60"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;pthread.h&gt;</span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">class</span> M
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
        M<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
        ~M<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            <span style="color: #0000dd;">cout</span><span style="color: #000080;">&lt;&lt;</span><span style="color: #FF0000;">&quot;M destructed...&quot;</span><span style="color: #000080;">&lt;&lt;</span>endl<span style="color: #008080;">;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #0000ff;">private</span><span style="color: #008080;">:</span>
        <span style="color: #0000ff;">int</span> i<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">class</span> B
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
        B<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
        <span style="color: #666666;">//! virtual ~B(){}</span>
        ~B<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">class</span> D<span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> B
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
        D<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
        ~D<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
    <span style="color: #0000ff;">private</span><span style="color: #008080;">:</span>
        M m<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span>
main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
    B <span style="color: #000040;">*</span> pb <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> D<span style="color: #008080;">;</span>
    <span style="color: #0000dd;">delete</span> pb<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>表明看来似乎合情合理，由于C++的多态特性，允许我们将一个子类地址赋给父类型的指针pb，释放对象时理所当然的对pb进行delete。但，在程序运行时，并没有输出M destructed&#8230;，即D::m的析构函数没有被调用，而m的析构函数是需要D::~D()来调用的，所以子类D的析构函数也没有被调用。这是很容易理解的，因为父类的析构函数不是virtual的。由此，我们得出结论，用来继承的父类的析构函数总应该是virtual的，除非你确定它绝对不会被用于多态。关于这一点，《Effective C++》里面已经讲到了。</p>
<p>除了上面的问题，我们还应该关心的是，尽管析构函数没有被调用，那M::i的空间被释放了吗？It&#8217;s a question！由于析构函数没有被调用，那么释放M::i的任务就完全落在了delete身上的了，那么delete做到了吗？It&#8217;s a very question！这又回到了<a href="http://www.dutor.net/index.php/2009/08/free-delete/" target="_blank">上一篇日志</a>中所描述的问题上了。我的观点是delete做到了它应该做的事情，它只负责释放当初new申请的空间，即对象<strong>本身</strong>，至于对象里面是否有动态申请的内存，那就不是delete而是对象析构函数自己的工作了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/08/delete-ag/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>pthread_mutex一例</title>
		<link>http://www.dutor.net/index.php/2009/08/pthread_mutex/</link>
		<comments>http://www.dutor.net/index.php/2009/08/pthread_mutex/#comments</comments>
		<pubDate>Fri, 21 Aug 2009 12:11:01 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[pthread]]></category>
		<category><![CDATA[多线程]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1139</guid>
		<description><![CDATA[<pre lang="cpp" line="1">
int
main()
{
	pthread_mutex_init(&#038;mutex, NULL); //~ 初始化互斥锁mutex
	pthread_t thread_id;
	void *exit_status;
	pthread_create(&#038;thread_id, NULL, thread_function, NULL); //~ 创建新线程
	for(int i = 0; i < 10; ++i)
	{
		usleep(10000); //~ 延时10ms
		//~ 访问共享数据
		pthread_mutex_lock(&#038;mutex);
		cout<<share<<endl;
		pthread_mutex_unlock(&#038;mutex);
	}
	pthread_join(thread_id, &#038;exit_status); //~ 等待线程结束
	pthread_mutex_destroy(&#038;mutex); //~ 销毁互斥锁
	return 0;
}
</pre>
]]></description>
			<content:encoded><![CDATA[
<div class="wp_codebox"><table><tr id="p113961"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
</pre></td><td class="code" id="p1139code61"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;pthread.h&gt;</span>
&nbsp;
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
&nbsp;
pthread_mutex_t mutex<span style="color: #008080;">;</span> <span style="color: #666666;">//~ 创建互斥锁mutex</span>
<span style="color: #0000ff;">int</span> share <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> <span style="color: #666666;">//~ 共享数据</span>
&nbsp;
<span style="color: #666666;">//~ 线程入口</span>
<span style="color: #0000ff;">void</span> <span style="color: #000040;">*</span> thread_function<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span> <span style="color: #000040;">*</span>arg<span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	<span style="color: #0000ff;">const</span> <span style="color: #0000ff;">int</span> N <span style="color: #000080;">=</span> <span style="color: #0000dd;">1000000</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> N<span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span>
	<span style="color: #008000;">&#123;</span>
		<span style="color: #666666;">//~ 访问共享数据</span>
		pthread_mutex_lock<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>mutex<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
		share<span style="color: #000040;">++</span><span style="color: #008080;">;</span>
		pthread_mutex_unlock<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>mutex<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span>
<span style="color: #0000ff;">int</span>
main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	pthread_mutex_init<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>mutex, <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">//~ 初始化互斥锁mutex</span>
	pthread_t thread_id<span style="color: #008080;">;</span>
	<span style="color: #0000ff;">void</span> <span style="color: #000040;">*</span>exit_status<span style="color: #008080;">;</span>
	pthread_create<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>thread_id, <span style="color: #0000ff;">NULL</span>, thread_function, <span style="color: #0000ff;">NULL</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">//~ 创建新线程</span>
	<span style="color: #0000ff;">for</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> i <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span> i <span style="color: #000080;">&lt;</span> <span style="color: #0000dd;">10</span><span style="color: #008080;">;</span> <span style="color: #000040;">++</span>i<span style="color: #008000;">&#41;</span>
	<span style="color: #008000;">&#123;</span>
		usleep<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">10000</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">//~ 延时10ms</span>
		<span style="color: #666666;">//~ 访问共享数据</span>
		pthread_mutex_lock<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>mutex<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
		<span style="color: #0000dd;">cout</span><span style="color: #000080;">&lt;&lt;</span>share<span style="color: #000080;">&lt;&lt;</span>endl<span style="color: #008080;">;</span>
		pthread_mutex_unlock<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>mutex<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	<span style="color: #008000;">&#125;</span>
	pthread_join<span style="color: #008000;">&#40;</span>thread_id, <span style="color: #000040;">&amp;</span>exit_status<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">//~ 等待线程结束</span>
	pthread_mutex_destroy<span style="color: #008000;">&#40;</span><span style="color: #000040;">&amp;</span>mutex<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">//~ 销毁互斥锁</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/08/pthread_mutex/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>用streambuf更改fstream的缓冲区</title>
		<link>http://www.dutor.net/index.php/2009/08/mod-stream-bufer/</link>
		<comments>http://www.dutor.net/index.php/2009/08/mod-stream-bufer/#comments</comments>
		<pubDate>Wed, 19 Aug 2009 12:09:54 +0000</pubDate>
		<dc:creator>dutor</dc:creator>
				<category><![CDATA[之语言特性]]></category>
		<category><![CDATA[边走编程]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[IO]]></category>

		<guid isPermaLink="false">http://www.dutor.net/?p=1127</guid>
		<description><![CDATA[源码之前，了无秘密。
<pre lang="cpp" line="1">
//~ demo.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <streambuf>
using namespace std;
//~ 测试代码 :)
int main()
{
	ifstream in("demo.cpp");
	char buffer[4096]="original content in this buffer";
	cout<<buffer<<endl;
	streambuf * ptrbuff = in.rdbuf(); //~ 将streambuf与文件句柄关联
	ptrbuf->pubsetbuf(bufer, 4096); //~ 设置缓冲区，即设置in的缓冲区
	cout<<buffer<<endl; //~ 此时bufer里面的内容还是original content in this buffer
	string str;
	in>>str; //~ 真正要输入时bufer才被填充为in的内容
	cout<<str<<endl;
	cout<<buffer<<endl;
	return 0;
} 
</pre>
另外，还有一个filebuf，用法相近。看了很多C++方面的书，从来没有那本书对I/O流做过详细的介绍。C里面有setbuf可以修改缓冲区，但我在fstream里面却没看到这么个setbuf，rdbuf倒是有一个，它返回streambuf类型的指针。搜索streambuf的用法，无果，MSDN里面看到streambuf有一个setbuf的成员，甚喜。编译器说，setbuf是私有的，再看MSDN，还有一个pubsetbuf，哟西！]]></description>
			<content:encoded><![CDATA[<p>源码之前，了无秘密。</p>

<div class="wp_codebox"><table><tr id="p112762"><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code" id="p1127code62"><pre class="cpp" style="font-family:monospace;"><span style="color: #666666;">//~ demo.cpp</span>
<span style="color: #339900;">#include &lt;iostream&gt;</span>
<span style="color: #339900;">#include &lt;fstream&gt;</span>
<span style="color: #339900;">#include &lt;string&gt;</span>
<span style="color: #339900;">#include &lt;streambuf&gt;</span>
<span style="color: #0000ff;">using</span> <span style="color: #0000ff;">namespace</span> std<span style="color: #008080;">;</span>
<span style="color: #666666;">//~ 测试代码 :)</span>
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
<span style="color: #008000;">&#123;</span>
	ifstream in<span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;demo.cpp&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
	<span style="color: #0000ff;">char</span> buffer<span style="color: #008000;">&#91;</span><span style="color: #0000dd;">4096</span><span style="color: #008000;">&#93;</span><span style="color: #000080;">=</span><span style="color: #FF0000;">&quot;original content in this buffer&quot;</span><span style="color: #008080;">;</span>
	<span style="color: #0000dd;">cout</span><span style="color: #000080;">&lt;&lt;</span>buffer<span style="color: #000080;">&lt;&lt;</span>endl<span style="color: #008080;">;</span>
	streambuf <span style="color: #000040;">*</span> ptrbuff <span style="color: #000080;">=</span> in.<span style="color: #007788;">rdbuf</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">//~ 将streambuf与文件句柄关联</span>
	ptrbuf<span style="color: #000040;">-</span><span style="color: #000080;">&gt;</span>pubsetbuf<span style="color: #008000;">&#40;</span>bufer, <span style="color: #0000dd;">4096</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span> <span style="color: #666666;">//~ 设置缓冲区，即设置in的缓冲区</span>
	<span style="color: #0000dd;">cout</span><span style="color: #000080;">&lt;&lt;</span>buffer<span style="color: #000080;">&lt;&lt;</span>endl<span style="color: #008080;">;</span> <span style="color: #666666;">//~ 此时bufer里面的内容还是original content in this buffer</span>
	string str<span style="color: #008080;">;</span>
	in<span style="color: #000080;">&gt;&gt;</span>str<span style="color: #008080;">;</span> <span style="color: #666666;">//~ 真正要输入时bufer才被填充为in的内容</span>
	<span style="color: #0000dd;">cout</span><span style="color: #000080;">&lt;&lt;</span>str<span style="color: #000080;">&lt;&lt;</span>endl<span style="color: #008080;">;</span>
	<span style="color: #0000dd;">cout</span><span style="color: #000080;">&lt;&lt;</span>buffer<span style="color: #000080;">&lt;&lt;</span>endl<span style="color: #008080;">;</span>
	<span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></td></tr></table></div>

<p>另外，还有一个filebuf，用法相近。看了很多C++方面的书，从来没有那本书对I/O流做过详细的介绍。C里面有setbuf可以修改缓冲区，但我在fstream里面却没看到这么个setbuf，rdbuf倒是有一个，它返回streambuf类型的指针。搜索streambuf的用法，无果，MSDN里面看到streambuf有一个setbuf的成员，甚喜。编译器说，setbuf是私有的，再看MSDN，还有一个pubsetbuf，哟西！</p>
]]></content:encoded>
			<wfw:commentRss>http://www.dutor.net/index.php/2009/08/mod-stream-bufer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>