﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-依睛(IT blog) 我回来了，PHP&lt;--&gt;C/C++ LINUX-随笔分类-C/C++学习资料库</title><link>http://www.cnitblog.com/guopingleee/category/5504.html</link><description>笨鸟
</description><language>zh-cn</language><lastBuildDate>Mon, 26 Sep 2011 09:25:43 GMT</lastBuildDate><pubDate>Mon, 26 Sep 2011 09:25:43 GMT</pubDate><ttl>60</ttl><item><title>C++内联函数与宏定义</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54625.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Mon, 16 Feb 2009 14:42:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54625.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54625.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54625.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54625.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54625.html</trackback:ping><description><![CDATA[
		<table style="BORDER-COLLAPSE: collapse; WORD-WRAP: break-word" cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td align="middle" height="25">
										<font style="FONT-SIZE: 14pt" color="#02368d">
												<b>C++内联函数与宏定义</b>
										</font>
										<br />
								</td>
						</tr>
						<tr>
								<td bgcolor="#d2dee2" height="1">
								</td>
						</tr>
						<tr>
								<td bgcolor="#ffffff" height="1">
								</td>
						</tr>
						<tr>
								<td align="middle">
										<table style="BORDER-COLLAPSE: collapse; WORD-WRAP: break-word" cellspacing="0" cellpadding="0" width="100%" border="0">
												<tbody>
														<tr>
																<td width="100%">
																		<div id="art" style="MARGIN: 15px" width="100%">
																				<p>
																						<strong>用内联取代宏：</strong>
																				</p>
																				<p style="COLOR: rgb(255,1,2)">
																						<strong>1.内联可调试；</strong>
																				</p>
																				<p style="COLOR: rgb(255,1,2)">
																						<strong>2.可进行类型安全检查或自动类型转换；</strong>
																				</p>
																				<p style="COLOR: rgb(255,1,2)">
																						<strong>3.可访问成员变量。</strong>
																				</p>
																				<p>
																						<strong>
																								<span style="COLOR: rgb(255,1,2)">另外，定义在类声明中的成员函数自动转化为内联函数。</span>
																								<br />
																						</strong>
																				</p>
																				<p>
																						<strong>文章（一）</strong>
																				</p>
																				<p>内联函数与宏定义<br />　　在C中，常用预处理语句#define来代替一个函数定义。例如：<br />　　　　#define MAX(a，b) ((a)&gt;(b)?(a):(b))<br />　　该语句使得程序中每个出现MAX(a,b)函数调用的地方都被宏定义中后面的表达式((a)&gt;(b)?(a):(b))所替换。</p>
																				<p>　　宏定义语句的书写格式有过分的讲究， MAX与括号之间不能有空格，所有的参数都要<br />　　放在括号里。尽管如此，它还是有麻烦：<br />　　　　int a=1，b=0；<br />　　　　MAX(a++,b)； //a被增值2次<br />　　　　MAX(a++,b+10)； //a被增值1次<br />　　　　MAX(a,"Hello")； //错误地比较int和字符串，没有参数类型检查<br />　　　　MAX( )函数的求值会由于两个参数值的大小不同而产生不同的副作用。<br />　　　　MAX(a++,b)的值为2，同时a的值为3；<br />　　　　MAX(a++,b+10)的值为10，同时a的值为2。<br />　　如果是普通函数，则MAX(a,"HellO")会受到函数调用的检查，但此处不会因为两个参数类型不同而被编译拒之门外。幸运的是，通过一个内联函数可以得到所有宏的替换效能和 所有可预见的状态以及常规函数的类型检查：<br />　　　　inline int MAX(int a，int b)<br />　　　　{<br />　　　　　return a&gt;b?a:b；<br />　　　　}</p>
																				<p>1.内联函数与宏的区别：</p>
																				<p>      传统的宏定义函数可能会引起一些麻烦。</p>
																				<p>      ex：</p>
																				<p>           #define F(x) x+x</p>
																				<p>           void main(){int i=1;F(i++);}</p>
																				<p>            这里x将被加两次。</p>
																				<p>        内联函数被编译器自动的用函数的形势添加进代码，而不会出现这种情况。</p>
																				<p>        内联函数的使用提高了效率（省去了很多函数调用汇编代码如：call和ret等）。</p>
																				<p>2.内联函数的使用：</p>
																				<p>         所有在类的声明中定义的函数将被自动认为是内联函数。</p>
																				<p>        class A()</p>
																				<p>       {</p>
																				<p>             void c();// not a inline function;</p>
																				<p>            void d(){ print("d() is a inline function.");}</p>
																				<p>        }</p>
																				<p>        如果想将一个全局函数定义为内联函数可用，inline 关键字。</p>
																				<p>        inline a(){print("a() is a inline function.");}</p>
																				<p>注意：</p>
																				<p>      在内联函数中如果有复杂操作将不被内联。如：循环和递归调用。</p>
																				<p>总结：</p>
																				<p>      将简单短小的函数定义为内联函数将会提高效率。</p>
																				<p>
																						<strong>文章（二）</strong>
																				</p>
																				<p>8.5.1 用内联取代宏代码 <br />C++ 语言支持函数内联，其目的是为了提高函数的执行效率（速度）。 <br />在 C程序中，可以用宏代码提高执行效率。宏代码本身不是函数，但使用起来象函数。预处理器用复制宏代码的方式代替函数调用，省去了参数压栈、生成汇编语言的 CALL调用、返回参数、执行return等过程，从而提高了速度。使用宏代码最大的缺点是容易出错，预处理器在复制宏代码时常常产生意想不到的边际效应。例如 <br />#define MAX(a, b)       (a) &gt; (b) ? (a) : (b) <br />语句  <br />result = MAX(i, j) + 2 ; <br />将被预处理器解释为 <br />result = (i) &gt; (j) ? (i) : (j) + 2 ; <br />由于运算符‘+’比运算符‘:’的优先级高，所以上述语句并不等价于期望的 <br />result = ( (i) &gt; (j) ? (i) : (j) ) + 2 ; <br />如果把宏代码改写为 <br />#define MAX(a, b)       ( (a) &gt; (b) ? (a) : (b) ) <br />则可以解决由优先级引起的错误。但是即使使用修改后的宏代码也不是万无一失的，例如语句 <br />result = MAX(i++, j); <br />将被预处理器解释为 <br />result = (i++) &gt; (j) ? (i++) : (j); <br />对于C++ 而言，使用宏代码还有另一种缺点：无法操作类的私有数据成员。 </p>
																				<p>让我们看看C++ 的“函数内联”是如何工作的。对于任何内联函数，编译器在符号表里放入函数的声明（包括名字、参数类型、返回值类型）。如果编译器没有发现内联函数存在错误，那么该函数的代码也被放入符号表里。在调用一个内联函数时，编译器首先检查调用是否正确（进行类型安全检查，或者进行自动类型转换，当然对所有的函数都一样）。如果正确，内联函数的代码就会直接替换函数调用，于是省去了函数调用的开销。这个过程与预处理有显著的不同，因为预处理器不能进行类型安全检查，或者进行自动类型转换。假如内联函数是成员函数，对象的地址（this）会被放在合适的地方，这也是预处理器办不到的。 <br />C++ 语言的函数内联机制既具备宏代码的效率，又增加了安全性，而且可以自由操作类的数据成员。所以在C++ 程序中，应该用内联函数取代所有宏代码，“断言assert”恐怕是唯一的例外。assert是仅在Debug版本起作用的宏，它用于检查“不应该”发生的情况。为了不在程序的Debug版本和Release版本引起差别，assert不应该产生任何副作用。如果assert是函数，由于函数调用会引起内存、代码的变动，那么将导致Debug版本与Release版本存在差异。所以assert不是函数，而是宏。（参见6.5节“使用断言”）<br />8.5.2 内联函数的编程风格 <br />关键字inline必须与函数定义体放在一起才能使函数成为内联，仅将inline放在函数声明前面不起任何作用。如下风格的函数Foo不能成为内联函数： <br />inline void Foo(int x, int y);  // inline仅与函数声明放在一起 <br />void Foo(int x, int y) <br />{ <br />… <br />} <br />而如下风格的函数Foo则成为内联函数： <br />void Foo(int x, int y);  <br />inline void Foo(int x, int y) // inline与函数定义体放在一起 <br />{ <br />… <br />} <br />所以说，inline是一种“用于实现的关键字”，而不是一种“用于声明的关键字”。一般地，用户可以阅读函数的声明，但是看不到函数的定义。尽管在大多数教科书中内联函数的声明、定义体前面都加了inline关键字，但我认为inline不应该出现在函数的声明中。这个细节虽然不会影响函数的功能，但是体现了高质量C++/C程序设计风格的一个基本原则：声明与定义不可混为一谈，用户没有必要、也不应该知道函数是否需要内联。 <br />定义在类声明之中的成员函数将自动地成为内联函数，例如 <br />class A <br />{ <br />public: <br />void Foo(int x, int y) { … }  // 自动地成为内联函数 <br />} <br />将成员函数的定义体放在类声明之中虽然能带来书写上的方便，但不是一种良好的编程风格，上例应该改成： <br />// 头文件 <br />class A <br />{ <br />public: <br />void Foo(int x, int y)；  <br />} <br />// 定义文件 <br />inline void A::Foo(int x, int y) <br />{ <br />… <br />} </p>
																				<p>8.5.3 慎用内联 <br />内联能提高函数的执行效率，为什么不把所有的函数都定义成内联函数？ <br />如果所有的函数都是内联函数，还用得着“内联”这个关键字吗？ <br />内联是以代码膨胀（复制）为代价，仅仅省去了函数调用的开销，从而提高函数的执行效率。如果执行函数体内代码的时间，相比于函数调用的开销较大，那么效率的收获会很少。另一方面，每一处内联函数的调用都要复制代码，将使程序的总代码量增大，消耗更多的内存空间。以下情况不宜使用内联： <br />（1）如果函数体内的代码比较长，使用内联将导致内存消耗代价较高。 <br />（2）如果函数体内出现循环，那么执行函数体内代码的时间要比函数调用的开销大。 <br />类的构造函数和析构函数容易让人误解成使用内联更有效。要当心构造函数和析构函数可能会隐藏一些行为，如“偷偷地”执行了基类或成员对象的构造函数和析构函数。所以不要随便地将构造函数和析构函数的定义体放在类声明中。 <br />一个好的编译器将会根据函数的定义体，自动地取消不值得的内联（这进一步说明了inline不应该出现在函数的声明中）。 <br />8.6 一些心得体会 <br />C++ 语言中的重载、内联、缺省参数、隐式转换等机制展现了很多优点，但是这些优点的背后都隐藏着一些隐患。正如人们的饮食，少食和暴食都不可取，应当恰到好处。我们要辨证地看待C++的新机制，应该恰如其分地使用它们。虽然这会使我们编程时多费一些心思，少了一些痛快，但这才是编程的艺术。 </p>
																				<p>第9章 类的构造函数、析构函数与赋值函数 <br />构造函数、析构函数与赋值函数是每个类最基本的函数。它们太普通以致让人容易麻痹大意，其实这些貌似简单的函数就象没有顶盖的下水道那样危险。 <br />每个类只有一个析构函数和一个赋值函数，但可以有多个构造函数（包含一个拷贝构造函数，其它的称为普通构造函数）。对于任意一个类A，如果不想编写上述函数，C++编译器将自动为A产生四个缺省的函数，如 <br />A(void); // 缺省的无参数构造函数 <br />A(const A &amp;a); // 缺省的拷贝构造函数 <br />~A(void); // 缺省的析构函数 <br />A &amp; operate =(const A &amp;a); // 缺省的赋值函数 </p>
																				<p>这不禁让人疑惑，既然能自动生成函数，为什么还要程序员编写？ <br />原因如下： <br />（1）如果使用“缺省的无参数构造函数”和“缺省的析构函数”，等于放弃了自主“初始化”和“清除”的机会，C++发明人Stroustrup的好心好意白费了。 <br />（2）“缺省的拷贝构造函数”和“缺省的赋值函数”均采用“位拷贝”而非“值拷贝”的方式来实现，倘若类中含有指针变量，这两个函数注定将出错。 </p>
																				<p>对于那些没有吃够苦头的C++程序员，如果他说编写构造函数、析构函数与赋值函数很容易，可以不用动脑筋，表明他的认识还比较肤浅，水平有待于提高。 <br />本章以类String的设计与实现为例，深入阐述被很多教科书忽视了的道理。String的结构如下： <br />class String <br />{ <br />  public: <br />String(const char *str = NULL); // 普通构造函数 <br />String(const String &amp;other); // 拷贝构造函数 <br />~ String(void); // 析构函数 <br />String &amp; operate =(const String &amp;other); // 赋值函数 <br />  private: <br />char   *m_data; // 用于保存字符串 <br />};</p>
																		</div>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/54625.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-16 22:42 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/16/54625.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>内联函数与c++宏相比的优点有哪些？</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54624.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Mon, 16 Feb 2009 14:40:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54624.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54624.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54624.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54624.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54624.html</trackback:ping><description><![CDATA[
		<div class="bc0">
				<div class="p90">
						<div class="f14 B wr" id="question_title">
								<cq>内联函数与c++宏相比的优点有哪些？</cq>
						</div>
						<div class="wr" id="question_info">
								<span class="red">
										<img height="16" src="http://img.baidu.com/img/iknow/icn_point.gif" width="16" align="absMiddle" /> 悬赏分：0</span> - <span class="gray">解决时间：2009-1-7 00:05</span></div>
						<div class="f14 wr" id="question_content">
								<cd>越详细越好，谢谢大哥大姐啦</cd>
						</div>
						<div class="f14 wr" id="question_sup">
						</div>
				</div>
				<div class="gray wr" id="question_author" align="right">提问者： <a href="http://passport.baidu.com/?business&amp;aid=6&amp;un=loveshenxue#2" target="_blank">loveshenxue</a> - <a href="http://www.baidu.com/search/zhidao_help.html#n5" target="_blank">试用期 一级</a></div>
		</div>
		<div class="rg_4">
		</div>
		<div class="rg_5">
		</div>
		<div class="rg_1">
		</div>
		<div class="mb12 bai">
				<div class="rr_1">
				</div>
				<div class="rr_2">
				</div>
				<div class="rr_3">
				</div>
				<div class="rr">
						<div class="t1">
								<div class="ico">
										<div class="ibest">
										</div>
								</div>最佳答案</div>
						<div class="bc0" style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; PADDING-BOTTOM: 5px; PADDING-TOP: 5px">
								<div class="wr">
										<div class="f14 p90 pl10" id="best_answer_content">
												<ca>函数内联 <br />用内联取代宏代码 <br />---------------- <br />C++ 语言支持函数内联<font style="BACKGROUND-COLOR: #7fffd4">，其目的是为了提高函数的执行效率（速度）。</font><br /><font style="BACKGROUND-COLOR: #ff1493">在C程序中，可以用宏代码提高执行效率。宏代码本身不是函数，但使用起来象函数。</font><br />预处理器用复制宏代码的方式代替函数调用，省去了参数压栈、生成汇编语言的CALL调用、 <br />返回参数、执行return等过程，从而提高了速度。 <br /><br />使用宏代码最大的缺点是容易出错，预处理器在复制宏代码时常常产生意想不到的边际效应。 <br /><br />对于C++ 而言，使用宏代码还有另一种缺点：无法操作类的私有数据成员。 <br /><br />让我们看看C++ 的"函数内联"是如何工作的。 <br />对于任何内联函数，编译器在符号表里放入函数的声明（包括名字、参数类型、返回值类型）。 <br />如果编译器没有发现内联函数存在错误，那么该函数的代码也被放入符号表里。 <br />在调用一个内联函数时，编译器首先检查调用是否正确 <br /><font style="BACKGROUND-COLOR: #ffc0cb">（进行类型安全检查，或者进行自动类型转换，当然对所有的函数都一样）。 <br />如果正确，内联函数的代码就会直接替换函数调用，于是省去了函数调用的开销。</font><br /><br />这个过程与预处理有显著的不同，因为预处理器不能进行类型安全检查，或者进行自动类型转换。 <br />假如内联函数是成员函数，对象的地址（this）会被放在合适的地方，这也是预处理器办不到的。 <br /><br />C++ 语言的函数内联机制既具备宏代码的效率，又增加了安全性，而且可以自由操作类的数据成员。 <br />所以在C++ 程序中，应该用内联函数取代所有宏代码，"断言assert"恐怕是唯一的例外。 <br />assert是仅在Debug版本起作用的宏，它用于检查"不应该"发生的情况。 <br />为了不在程序的Debug版本和Release版本引起差别，assert不应该产生任何副作用。 <br />如果assert是函数，由于函数调用会引起内存、代码的变动，那么将导致Debug版本与Release版本存在差异。 <br />所以assert不是函数，而是宏。</ca>
										</div>
								</div>
						</div>
				</div>
		</div>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/54624.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-16 22:40 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/16/54624.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++堆、栈、自由存储区、全局/静态存储区和常量存储区</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54601.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Mon, 16 Feb 2009 03:25:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54601.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54601.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54601.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54601.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54601.html</trackback:ping><description><![CDATA[
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="title" valign="bottom" align="middle" bgcolor="#f7fcff">
										<strong>C++堆、栈、自由存储区、全局/静态存储区和常量存储区</strong>
								</td>
						</tr>
						<tr>
								<td class="fbrq" align="middle" bgcolor="#f7fcff">发布日期：2007-8-18 7:56:13  点击:
<script src="/Click.asp?NewsID=0781807565551114"></script>
   <a href="http://forums.zxbc.cn/" target="_blank"><span class="color">进入论坛</span></a></td>
						</tr>
						<tr>
								<td class="comment" bgcolor="#f7fcff">    在C++中，内存分成5个区，他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。<br />  <font color="#ee82ee">  栈，就是那些由编译器在需要的时候分配，在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。<br /></font>    <font color="#006400">堆，就是那些由new分配的内存块，他们的释放编译器不去管，由我们的应用程序去控制，一般一个new就要对应一个delete。如果程序员没有释放掉，那么在程序结束后，操作系统会自动回收。<br /></font>    自由存储区，就是那些由malloc等分配的内存块，他和堆是十分相似的，不过它是用free来结束自己的生命的。<br />    全局/静态存储区，全局变量和静态变量被分配到同一块内存中，在以前的C语言中，全局变量又分为初始化的和未初始化的，在C++里面没有这个区分了，他们共同占用同一块内存区。<br />    常量存储区，这是一块比较特殊的存储区，他们里面存放的是常量，不允许修改（当然，你要通过非正当手段也可以修改，而且方法很多）<br /><strong>明确区分堆与栈<br /></strong>    在bbs上，堆与栈的区分问题，似乎是一个永恒的话题，由此可见，初学者对此往往是混淆不清的，所以我决定拿他第一个开刀。<br />    首先，我们举一个例子：<br />    void f() { int* p=new int[5]; } <br />    这条短短的一句话就包含了堆与栈，看到new，我们首先就应该想到，我们分配了一块堆内存，那么指针p呢？他分配的是一块栈内存，所以这句话的意思就是： 在栈内存中存放了一个指向一块堆内存的指针p。在程序会先确定在堆中分配内存的大小，然后调用operator new分配内存，然后返回这块内存的首地址，放入栈中，他在VC6下的汇编代码如下：<br />    00401028   push        14h<br />    0040102A   call        operator new (00401060)<br />    0040102F   add         esp,4<br />    00401032   mov         dword ptr [ebp-8],eax<br />    00401035   mov         eax,dword ptr [ebp-8]<br />    00401038   mov         dword ptr [ebp-4],eax<br />    这里，我们为了简单并没有释放内存，那么该怎么去释放呢？是delete p么？澳，错了，应该是delete []p，这是为了告诉编译器：我删除的是一个数组，VC6就会根据相应的Cookie信息去进行释放内存的工作。<br />    好了，我们回到我们的主题：堆和栈究竟有什么区别？ <br />    主要的区别由以下几点：<br />    1、管理方式不同；<br />    2、空间大小不同；<br />    3、能否产生碎片不同；<br />    4、生长方向不同；<br />    5、分配方式不同；<br />    6、分配效率不同；<br />    管理方式：对于栈来讲，是由编译器自动管理，无需我们手工控制；对于堆来说，释放工作由程序员控制，容易产生memory leak。</td>
						</tr>
				</tbody>
		</table>空间大小：一般来讲在32位系统下，堆内存可以达到4G的空间，从这个角度来看堆内存几乎是没有什么限制的。但是对于栈来讲，一般都是有一定的空间大小的，例如，在VC6下面，默认的栈空间大小是1M（好像是，记不清楚了）。当然，我们可以修改：    <br />    打开工程，依次操作菜单如下：Project-&gt;Setting-&gt;Link，在Category 中选中Output，然后在Reserve中设定堆栈的最大值和commit。<br />注意：reserve最小值为4Byte；commit是保留在虚拟内存的页文件里面，它设置的较大会使栈开辟较大的值，可能增加内存的开销和启动时间。<br />    碎片问题：对于堆来讲，频繁的new/delete势必会造成内存空间的不连续，从而造成大量的碎片，使程序效率降低。对于栈来讲，则不会存在这个问题， 因为栈是先进后出的队列，他们是如此的一一对应，以至于永远都不可能有一个内存块从栈中间弹出，在他弹出之前，在他上面的后进的栈内容已经被弹出，详细的 可以参考数据结构，这里我们就不再一一讨论了。<br />    生长方向：对于堆来讲，生长方向是向上的，也就是向着内存地址增加的方向；对于栈来讲，它的生长方向是向下的，是向着内存地址减小的方向增长。<br />    分配方式：堆都是动态分配的，没有静态分配的堆。栈有2种分配方式：静态分配和动态分配。静态分配是编译器完成的，比如局部变量的分配。动态分配由alloca函数进行分配，但是栈的动态分配和堆是不同的，他的动态分配是由编译器进行释放，无需我们手工实现。<br />    分配效率：栈是机器系统提供的数据结构，计算机会在底层对栈提供支持：分配专门的寄存器存放栈的地址，压栈出栈都有专门的指令执行，这就决定了栈的效率比 较高。堆则是C/C++函数库提供的，它的机制是很复杂的，例如为了分配一块内存，库函数会按照一定的算法（具体的算法可以参考数据结构/操作系统）在堆 内存中搜索可用的足够大小的空间，如果没有足够大小的空间（可能是由于内存碎片太多），就有可能调用系统功能去增加程序数据段的内存空间，这样就有机会分 到足够大小的内存，然后进行返回。显然，堆的效率比栈要低得多。<br />    从这里我们可以看到，堆和栈相比，由于大量new/delete的使用，容易造成大量的内存碎片；由于没有专门的系统支持，效率很低；由于可能引发用户态 和核心态的切换，内存的申请，代价变得更加昂贵。所以栈在程序中是应用最广泛的，就算是函数的调用也利用栈去完成，函数调用过程中的参数，返回地址， EBP和局部变量都采用栈的方式存放。所以，我们推荐大家尽量用栈，而不是用堆。<br />    虽然栈有如此众多的好处，但是由于和堆相比不是那么灵活，有时候分配大量的内存空间，还是用堆好一些。<br />    无论是堆还是栈，都要防止越界现象的发生（除非你是故意使其越界），因为越界的结果要么是程序崩溃，要么是摧毁程序的堆、栈结构，产生以想不到的结果,就 算是在你的程序运行过程中，没有发生上面的问题，你还是要小心，说不定什么时候就崩掉，那时候debug可是相当困难的：）<br />对了，还有一件事，如果有人把堆栈合起来说，那它的意思是栈，可不是堆，呵呵，清楚了？<br /><strong>static用来控制变量的存储方式和可见性<br /></strong>       函数内部定义的变量，在程序执行到它的定义处时，编译器为它在栈上分配空间，函数在栈上分配的空间在此函数执行结束时会释放掉，这样就产生了一个问题: 如果想将函数中此变量的值保存至下一次调用时，如何实现？ 最容易想到的方法是定义一个全局的变量，但定义为一个全局变量有许多缺点，最明显的缺点是破坏了此变量的访问范围（使得在此函数中定义的变量，不仅仅受此 函数控制）。 
<p>       需要一个数据对象为整个类而非某个对象服务,同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部，对外不可见。</p><p>       static的内部机制：<br />       静态数据成员要在程序一开始运行时就必须存在。因为函数在程序运行中被调用，所以静态数据成员不能在任何函数内分配空间和初始化。<br />       这样，它的空间分配有三个可能的地方，一是作为类的外部接口的头文件，那里有类声明；二是类定义的内部实现，那里有类的成员函数定义；三是应用程序的main（）函数前的全局数据声明和定义处。<br />      静态数据成员要实际地分配空间，故不能在类的声明中定义（只能声明数据成员）。类声明只声明一个类的“尺寸和规格”，并不进行实际的内存分配，所以在类声 明中写成定义是错误的。它也不能在头文件中类声明的外部定义，因为那会造成在多个使用该类的源文件中，对其重复定义。<br />      static被引入以告知编译器，将变量存储在程序的静态存储区而非栈上空间，静态<br />数据成员按定义出现的先后顺序依次初始化，注意静态成员嵌套时，要保证所嵌套的成员已经初始化了。消除时的顺序是初始化的反顺序。</p><p>       static的优势：<br />       可以节省内存，因为它是所有对象所公有的，因此，对多个对象来说，静态数据成员只存储一处，供所有对象共用。静态数据成员的值对每个对象都是一样，但它的 值是可以更新的。只要对静态数据成员的值更新一次，保证所有对象存取更新后的相同的值，这样可以提高时间效率。</p><p>        引用静态数据成员时，采用如下格式：<br />         &lt;类名&gt;::&lt;静态成员名&gt;<br />    如果静态数据成员的访问权限允许的话(即public的成员)，可在程序中，按上述格式<br />来引用静态数据成员。</p><p>       PS:<br />      (1)类的静态成员函数是属于整个类而非类的对象，所以它没有this指针，这就导致<br />了它仅能访问类的静态数据和静态成员函数。<br />      (2)不能将静态成员函数定义为虚函数。<br />      (3)由于静态成员声明于类中，操作于其外，所以对其取地址操作，就多少有些特殊<br />，变量地址是指向其数据类型的指针 ，函数地址类型是一个“nonmember函数指针”。 </p><p></p><p>      (4)由于静态成员函数没有this指针，所以就差不多等同于nonmember函数，结果就<br />产生了一个意想不到的好处：成为一个callback函数，使得我们得以将C++和C-based X W<br />indow系统结合，同时也成功的应用于线程函数身上。<br />      (5)static并没有增加程序的时空开销，相反她还缩短了子类对父类静态成员的访问<br />时间，节省了子类的内存空间。<br />      (6)静态数据成员在&lt;定义或说明&gt;时前面加关键字static。<br />      (7)静态数据成员是静态存储的，所以必须对它进行初始化。<br />      (8)静态成员初始化与一般数据成员初始化不同:<br />      初始化在类体外进行，而前面不加static，以免与一般静态变量或对象相混淆；<br />      初始化时不加该成员的访问权限控制符private，public等；<br />           初始化时使用作用域运算符来标明它所属类；<br />           所以我们得出静态数据成员初始化的格式：<br />         &lt;数据类型&gt;&lt;类名&gt;::&lt;静态数据成员名&gt;=&lt;值&gt;<br />      (9)为了防止父类的影响，可以在子类定义一个与父类相同的静态变量，以屏蔽父类的影响。这里有一点需要注意：我们说静态成员为父类和子类共享，但我们有 重复定义了静态成员，这会不会引起错误呢？不会，我们的编译器采用了一种绝妙的手法：name-mangling 用以生成唯一的标志。<br /><br /></p><img src ="http://www.cnitblog.com/guopingleee/aggbug/54601.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-16 11:25 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/16/54601.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> C++堆、栈、自由存储区、全局/静态存储区和常量存储区收藏</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54599.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Mon, 16 Feb 2009 03:23:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54599.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54599.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54599.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54599.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54599.html</trackback:ping><description><![CDATA[
		<p>一个由c/C++编译的程序占用的内存分为以下几个部分 <br />1、栈区（stack）— 由编译器自动分配释放 ，存放函数的参数值，局部变量的值等。其操作方式类似于数据结构中的栈。 <br />2、堆区（heap） — 一般由程序员分配释放， 若程序员不释放，程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事，分配方式倒是类似于链表，呵呵。 <br />3、全局区（静态区）（static）—，全局变量和静态变量的存储是放在一块的，初始化的全局变量和静态变量在一块区域， 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放 <br />4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放 <br />5、程序代码区—存放函数体的二进制代码。</p>
		<p>
				<br />二、例子程序 <br />这是一个前辈写的，非常详细 <br />//main.cpp <br />int a = 0; 全局初始化区 <br />char *p1; 全局未初始化区 <br />main() <br />{ <br />int b; 栈 <br />char s[] = "abc"; 栈 <br />char *p2; 栈 <br />char *p3 = "123456"; 123456在常量区，p3在栈上。 <br />static int c =0； 全局（静态）初始化区 <br />p1 = (char *)malloc(10); <br />p2 = (char *)malloc(20); <br />分配得来得10和20字节的区域就在堆区。 <br />strcpy(p1, "123456"); 123456放在常量区，编译器可能会将它与p3所指向的"123456"优化成一个地方。 <br />}</p>
		<p>
				<br />二、堆和栈的理论知识 <br />2.1申请方式 <br />stack: <br />由系统自动分配。 例如，声明在函数中一个局部变量 int b; 系统自动在栈中为b开辟空间 <br />heap: <br />需要程序员自己申请，并指明大小，在c中malloc函数 <br />如p1 = (char *)malloc(10); <br />在C++中用new运算符 <br />如p2 = (char *)malloc(10); <br />但是注意p1、p2本身是在栈中的。</p>
		<p>
				<br />2.2 <br />申请后系统的响应 <br />栈：只要栈的剩余空间大于所申请空间，系统将为程序提供内存，否则将报异常提示栈溢出。 <br />堆：首先应该知道操作系统有一个记录空闲内存地址的链表，当系统收到程序的申请时， <br />会遍历该链表，寻找第一个空间大于所申请空间的堆结点，然后将该结点从空闲结点链表中删除，并将该结点的空间分配给程序，另外，对于大多数系统，会在这块内存空间中的首地址处记录本次分配的大小，这样，代码中的delete语句才能正确的释放本内存空间。另外，由于找到的堆结点的大小不一定正好等于申请的大小，系统会自动的将多余的那部分重新放入空闲链表中。</p>
		<p>2.3申请大小的限制 <br />栈：在Windows下,栈是向低地址扩展的数据结构，是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的，在 WINDOWS下，栈的大小是2M（也有的说是1M，总之是一个编译时就确定的常数），如果申请的空间超过栈的剩余空间时，将提示overflow。因此，能从栈获得的空间较小。 <br />堆：堆是向高地址扩展的数据结构，是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的，自然是不连续的，而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见，堆获得的空间比较灵活，也比较大。</p>
		<p>
				<br />2.4申请效率的比较： <br />栈由系统自动分配，速度较快。但程序员是无法控制的。 <br />堆是由new分配的内存，一般速度比较慢，而且容易产生内存碎片,不过用起来最方便. <br />另外，在WINDOWS下，最好的方式是用VirtualAlloc分配内存，他不是在堆，也不是在栈是直接在进程的地址空间中保留一快内存，虽然用起来最不方便。但是速度快，也最灵活。</p>
		<p>2.5堆和栈中的存储内容 <br />栈： 在函数调用时，第一个进栈的是主函数中后的下一条指令（函数调用语句的下一条可执行语句）的地址，然后是函数的各个参数，在大多数的C编译器中，参数是由右往左入栈的，然后是函数中的局部变量。注意静态变量是不入栈的。 <br />当本次函数调用结束后，局部变量先出栈，然后是参数，最后栈顶指针指向最开始存的地址，也就是主函数中的下一条指令，程序由该点继续运行。 <br />堆：一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。</p>
		<p>2.6存取效率的比较</p>
		<p>char s1[] = "aaaaaaaaaaaaaaa"; <br />char *s2 = "bbbbbbbbbbbbbbbbb"; <br />aaaaaaaaaaa是在运行时刻赋值的； <br />而bbbbbbbbbbb是在编译时就确定的； <br />但是，在以后的存取中，在栈上的数组比指针所指向的字符串(例如堆)快。 <br />比如： <br />#include <br />void main() <br />{ <br />char a = 1; <br />char c[] = "1234567890"; <br />char *p ="1234567890"; <br />a = c[1]; <br />a = p[1]; <br />return; <br />} <br />对应的汇编代码 <br />10: a = c[1]; <br />00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh] <br />0040106A 88 4D FC mov byte ptr [ebp-4],cl <br />11: a = p[1]; <br />0040106D 8B 55 EC mov edx,dword ptr [ebp-14h] <br />00401070 8A 42 01 mov al,byte ptr [edx+1] <br />00401073 88 45 FC mov byte ptr [ebp-4],al <br />第一种在读取时直接就把字符串中的元素读到寄存器cl中，而第二种则要先把指针值读到edx中，在根据edx读取字符，显然慢了。</p>
		<p>
				<br />2.7小结： <br />堆和栈的区别可以用如下的比喻来看出： <br />使用栈就象我们去饭馆里吃饭，只管点菜（发出申请）、付钱、和吃（使用），吃饱了就走，不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作，他的好处是快捷，但是自由度小。 <br />使用堆就象是自己动手做喜欢吃的菜肴，比较麻烦，但是比较符合自己的口味，而且自由度大。</p>
		<p>1、内存分配方面：</p>
		<p>    堆：一般由程序员分配释放， 若程序员不释放，程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事，分配方式是类似于链表。可能用到的关键字如下：new、malloc、delete、free等等。</p>
		<p>    栈：由编译器(Compiler)自动分配释放，存放函数的参数值，局部变量的值等。其操作方式类似于数据结构中的栈。</p>
		<p>2、申请方式方面：</p>
		<p>    堆：需要程序员自己申请，并指明大小。在c中malloc函数如p1 = (char *)malloc(10)；在C++中用new运算符，但是注意p1、p2本身是在栈中的。因为他们还是可以认为是局部变量。</p>
		<p>    栈：由系统自动分配。 例如，声明在函数中一个局部变量 int b；系统自动在栈中为b开辟空间。</p>
		<p>3、系统响应方面：</p>
		<p>    堆：操作系统有一个记录空闲内存地址的链表，当系统收到程序的申请时，会遍历该链表，寻找第一个空间大于所申请空间的堆结点，然后将该结点从空闲结点链表中删除，并将该结点的空间分配给程序，另外，对于大多数系统，会在这块内存空间中的首地址处记录本次分配的大小，这样代码中的delete语句才能正确的释放本内存空间。另外由于找到的堆结点的大小不一定正好等于申请的大小，系统会自动的将多余的那部分重新放入空闲链表中。</p>
		<p>    栈：只要栈的剩余空间大于所申请空间，系统将为程序提供内存，否则将报异常提示栈溢出。</p>
		<p>4、大小限制方面：</p>
		<p>    堆：是向高地址扩展的数据结构，是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的，自然是不连续的，而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见，堆获得的空间比较灵活，也比较大。</p>
		<p>    栈：在Windows下, 栈是向低地址扩展的数据结构，是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的，在WINDOWS下，栈的大小是固定的（是一个编译时就确定的常数），如果申请的空间超过栈的剩余空间时，将提示overflow。因此，能从栈获得的空间较小。</p>
		<p>5、效率方面：</p>
		<p>    堆：是由new分配的内存，一般速度比较慢，而且容易产生内存碎片，不过用起来最方便，另外，在WINDOWS下，最好的方式是用VirtualAlloc分配内存，他不是在堆，也不是在栈是直接在进程的地址空间中保留一快内存，虽然用起来最不方便。但是速度快，也最灵活。</p>
		<p>    栈：由系统自动分配，速度较快。但程序员是无法控制的。</p>
		<p>6、存放内容方面：</p>
		<p>    堆：一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。</p>
		<p>    栈：在函数调用时第一个进栈的是主函数中后的下一条指令（函数调用语句的下一条可执行语句）的地址然后是函数的各个参数，在大多数的C编译器中，参数是由右往左入栈，然后是函数中的局部变量。 注意: 静态变量是不入栈的。当本次函数调用结束后，局部变量先出栈，然后是参数，最后栈顶指针指向最开始存的地址，也就是主函数中的下一条指令，程序由该点继续运行。</p>
		<p>7、存取效率方面：</p>
		<p>    堆：char *s1 = "Hellow Word"；是在编译时就确定的；</p>
		<p>    栈：char s1[] = "Hellow Word"； 是在运行时赋值的；用数组比用指针速度要快一些，因为指针在底层汇编中需要用edx寄存器中转一下，而数组在栈上直接读取。</p>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/54599.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-16 11:23 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/16/54599.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>常量函数、常量引用参数、常量引用返回值[C++] </title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54598.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Mon, 16 Feb 2009 03:19:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54598.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54598.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54598.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54598.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54598.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 常量函数、常量引用参数、常量引用返回值[C++]																		1. 关于常量引用正像在C语言中使用指针一样，C++中通常使用引用 有一个函数... foo()并且这个函数返回一个引用...... &amp; foo()...., 一个指向位图(Bitmap)的引用 ...Bitmap &amp; foo().... 并且这个位图(bitmap)是常量con...&nbsp;&nbsp;<a href='http://www.cnitblog.com/guopingleee/archive/2009/02/16/54598.html'>阅读全文</a><img src ="http://www.cnitblog.com/guopingleee/aggbug/54598.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-16 11:19 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/16/54598.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>值和传引用、传地址的区别是什么？</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54597.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Mon, 16 Feb 2009 03:18:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54597.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54597.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54597.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54597.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54597.html</trackback:ping><description><![CDATA[
		<h1 class="ContentTitle">
				<strong>传值和传引用、传地址的区别是什么？ </strong>
		</h1>
		<h2 class="ContentAuthor">作者:dh20156 日期:2007-06-18</h2>
		<div class="Content-Info">
				<div class="InfoOther">字体大小: <a accesskey="1" href="javascript:SetFont('12px')">小</a><a accesskey="2" href="javascript:SetFont('14px')">中</a><a accesskey="3" href="javascript:SetFont('16px')">大</a></div>
				<div class="InfoAuthor">
						<img style="MARGIN: 0px 2px -6px 0px" alt="" src="http://www.v-ec.com/dh20156/images/weather/hn2_sunny.gif" />
						<img alt="" src="http://www.v-ec.com/dh20156/images/weather/hn2_t_sunny.gif" />
						<img style="MARGIN: 0px 2px -1px 0px" alt="" src="http://www.v-ec.com/dh20156/images/level3.gif" />
				</div>
		</div>
		<div class="Content-body" id="logPanel">
				<p>传值，   <br />  是把实参的值赋值给行参   <br />  那么对行参的修改，<font color="#ff0000">不会影响实参的值</font>   <br />    <br />  传地址   <br />  是传值的一种特殊方式，只是他传递的是地址，不是普通的如int   <br />  那么传地址以后，实参和行参都<font color="#ff0000">指向同一个对象</font>   <br />    <br />  传引用   <br />  真正的以地址的方式传递参数   <br />  传递以后，行参和实参<font color="#ff0000">都是同一个对象</font>，只是他们名字不同而已   <br />  对行参的修改将影响实参的值<br /><br />-----------------------------------------------------------------------------------<br /><br />觉得从函数调用的角度理解比较好   <br />    <br />  传值：   <br />  函数参数压栈的是参数的副本。   <br />  任何的修改是在副本上作用，没有作用在原来的变量上。   <br />    <br />  传指针：   <br />  压栈的是指针变量的副本。   <br />  当你对指针解指针操作时，其值是指向原来的那个变量，所以对原来变量操作。   <br />    <br />  传引用：   <br />  压栈的是引用的副本。由于引用是指向某个变量的，对引用的操作其实就是对他指向的变量的操作。（作用和传指针一样，只是引用少了解指针的草纸）  <br /><br />-----------------------------------------------------------------------------------<br />函数参数传递机制的基本理论   <br />  　　函数参数传递机制问题在本质上是调用函数（过程）和被调用函数（过程）在调用发生时进行通信的方法问题。基本的参数传递机制有两种：值传递和引用传递。以下讨论称调用其他函数的函数为主调函数，被调用的函数为被调函数。   <br />  　　值传递（passl-by-value）过程中，被调函数的形式参数作为被调函数的局部变量处理，即在堆栈中开辟了内存空间以存放由主调函数放进来的实参的值，从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行，不会影响主调函数的实参变量的值。   <br />  　　引用传递(pass-by-reference)过程中，被调函数的形式参数虽然也作为局部变量在堆栈中开辟了内存空间，但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址，即通过堆栈中存放的地址访问主调函数中的实参变量。正因为如此，被调函数对形参做的任何操作都影响了主调函数中的   <br />  实参变量。   <br /><br /><br />-----------------------------------------------------------------------------------<br /><br />仅讨论一下值传递和引用：   <br />  所谓值传递，就是说仅将对象的值传递给目标对象，就相当于copy；系统将为目标对象重新开辟一个完全相同的内存空间。   <br />  所谓引用，就是说将对象在内存中的地址传递给目标对象，就相当于使<font color="#ff0000">目标对象和原始对象对应同一个内存存储空间</font>。此时，如果对目标对象进行修改，内存中的数据也会改变。</p>
				<p>
						<strong>
								<font color="#000000">原文地址</font>
						</strong>
						<a href="http://topic.csdn.net/t/20051207/06/4442668.html" target="_blank">http://topic.csdn.net/t/20051207/06/4442668</a>
				</p>
		</div>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/54597.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-16 11:18 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/16/54597.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>]c++重点知识 </title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54595.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Mon, 16 Feb 2009 02:52:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54595.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54595.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54595.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54595.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54595.html</trackback:ping><description><![CDATA[
		<font size="4">论坛: <a href="http://www.ieee.org.cn/list.asp?boardid=61&amp;page=2&amp;action">http://www.ieee.org.cn/list.asp?boardid=61&amp;page=2&amp;action</a>=<br /><br />看看了这总结的真不错, 在反复看看, 书要反复读, 再反复看, 看自己还有哪些遗漏处.<br /></font>
		<table class="luntan_font_title_2" cellspacing="0" cellpadding="0" width="96%" align="center" border="0">
				<tbody>
						<tr>
								<td width="80%">
										<font size="4">
												<b>]c++重点知识</b> 　　<span class="pt9_1"><font color="#ffffff">[阅读：
<script src="/blog/view_count.asp?id=1440442&amp;poster_userid=654318"></script>
 1208]</font></span></font>
								</td>
								<td align="right" width="20%">
										<font size="4">
										</font>
								</td>
						</tr>
				</tbody>
		</table>
		<table cellspacing="0" cellpadding="0" width="96%" align="center" border="0">
				<tbody>
						<tr>
								<td width="100%" colspan="4" height="20">
										<font size="4">
										</font>
								</td>
						</tr>
						<tr>
								<td class="luntan_font" width="100%" colspan="4">
										<p>
												<font size="4">C++知识点 <br />一、＃i nclude “filename.h”和＃i nclude filename.h&gt;的区别<br />＃i nclude “filename.h”是指编译器将从当前工作目录上开始查找此文件<br />＃i nclude filename.h&gt;是指编译器将从标准库目录中开始查找此文件</font>
										</p>
										<p>
												<font size="4">二、头文件的作用<br />加强安全检测<br />通过头文件可能方便地调用库功能，而不必关心其实现方式</font>
										</p>
										<p>
												<font size="4">三、* , &amp;修饰符的位置<br /><font color="#ff1493">对于*和&amp;修饰符，为了避免误解，最好将修饰符紧靠变量名</font></font>
										</p>
										<p>
												<font size="4">四、if语句<br />不要将布尔变量与任何值进行比较，那会很容易出错的。<br />整形变量必须要有类型相同的值进行比较<br /><font color="#ff1493">浮点变量最好少比点，就算要比也要有值进行限制</font><br /><font color="#006400">指针变量要和NULL进行比较，不要和布尔型和整形比较</font></font>
										</p>
										<p>
												<font size="4">五、const和#define的比较<br /><font color="#ff1493">const有数据类型，<br /></font><font color="#ffff00"><font color="#a52a2a">#define没有数据类型</font><br /></font><font color="#ee82ee">个别编译器中const可以进行调试，#define不可以进行调试</font><br />在类中定义常量有两种方式<br />1、 在类在声明常量，但不赋值，在构造函数初始化表中进行赋值；<br />2、 用枚举代替const常量。</font>
										</p>
										<p>
												<font size="4">六、C++函数中值的传递方式<br />有三种方式：值传递(Pass by value)、指针传递(Pass by pointer)、引用传递(Pass by reference)<br />void fun(char c) //pass by value<br />void fun(char *str) //pass by pointer<br /><font color="#ff1493">void fun(char &amp;str) //pass by reference</font><br />如果输入参数是以值传递的话，最好使用引用传递代替，因为引用传递省去了临时对象的构造和析构<br />函数的类型不能省略，就算没有也要加个void</font>
										</p>
										<p>
												<font size="4">七、<font color="#ff1493">函数体中的指针或引用常量不能被返回<br />Char *func(void)<br />{<br />char str[]=”Hello Word”;<br />//这个是不能被返回的，因为str是个指向栈内存的指针，不是一般的值，函数结束后会被注销掉<br /></font>return str; <br />}<br /><br />函数体内的指针变量并不会随着函数的消亡而自动释放<br /></font>
										</p>
										<p>
												<font size="4">例子: <br />char * fun(void)<br />{<br />    char    * st="hello ssssssssssssss             ";</font>
										</p>
										<p>
												<font size="4">    return st; <font color="#ff1493">//函数体内的指针变量并不会随着函数的消亡而自动释放<br /></font>}<br />void main() <br />{ <br />     char    *p3;<br />    p3 = fun()<br />    printf(p3);</font>
										</p>
										<p>
												<font size="4">} <br /><br /><br />八、一个内存拷贝函数的实现体<br />void *memcpy(void *pvTo,const void *pvFrom,size_t size)<br />{<br />assert((pvTo!=NULL)&amp;&amp;(pvFrom!=NULL));<br />byte *pbTo=(byte*)pvTo; //防止地址被改变<br />byte *pbFrom=(byte*)pvFrom;<br />while (size-- &gt;0)<br />pbTo++ = pbForm++;<br />return pvTo;<br />} </font>
										</p>
										<p>
												<font size="4">九、内存的分配方式<br />分配方式有三种，请记住，说不定那天去面试的时候就会有人问你这问题<br />1、<font color="#ff1493"> 静态存储区，是在程序编译时就已经分配好的，在整个运行期间都存在，如全局变量、常量。<br />2、 栈上分配，函数内的局部变量就是从这分配的，但分配的内存容易有限。<br />3、 堆上分配，也称动态分配，如我们用new,malloc分配内存，用delete,free来释放的内存。</font></font>
										</p>
										<p>
												<font size="4">十、内存分配的注意事项<br /><font color="#ff0000">用new或malloc分配内存时，必须要对此指针赋初值。<br />用delete 或free释放内存后，必须要将指针指向NULL<br /></font><font color="#ff1493">不能修改指向常量的指针数据</font></font>
										</p>
										<p>
												<font size="4">十一、内容复制与比较<br />//数组……<br />char a[]=”Hello Word!”;<br />char b[10];<br />strcpy(b,a);<br />if (strcmp(a,b)==0)<br />{}<br />//指针……<br />char a[]=”Hello Word!”;<br />char *p;<br />p=new char[strlen(a)+1];<br />strcpy(p,a);<br />if (strcmp(p,a)==0)<br />{}</font>
										</p>
										<p>
												<font size="4">十二、sizeof的问题<br />记住一点，C++无法知道指针所指对象的大小，指针的大小永远为4字节<br />char a[]=”Hello World!”<br />char *p=a;<br />count sizeof(a) end; //12字节<br />count sizeof(p) endl; //4字节<br />而且，在函数中，数组参数退化为指针，所以下面的内容永远输出为4<br />void fun(char a[1000])<br />{<br />count sizeof(a) endl; //输出4而不是1000<br />}</font>
										</p>
										<p>
												<font size="4">十三、关于指针<br />1、 指针创建时必须被初始化<br />2、 指针在free 或delete后必须置为NULL<br />3、 指针的长度都为4字节<br />４、释放内存时，如果是数组指针，必须要释放掉所有的内存，如<br />char *p=new char[100];<br />strcpy(p,”Hello World”);<br />delete []p; //注意前面的[]号<br />p=NULL;//置为NULL<br />５、数组指针的内容不能超过数组指针的最大容易。<br />如:<br />char *p=new char[5];<br />strcpy(p,”Hello World”); //报错 目标容易不够大<br />delete []p; //注意前面的［］号<br />p=NULL;</font>
										</p>
										<p>
												<font size="4">十四、关于malloc/free 和new /delete<br />l malloc/free 是C/C+的内存分配符，new /delete是C++的内存分配符。<br />l 注意：malloc/free是库函数，new/delete是运算符<br />l malloc/free不能执行构造函数与析构函数，而new/delete可以<br />l new/delete不能在C上运行，所以malloc/free不能被淘汰<br />l 两者都必须要成对使用<br />l C++中可以使用_set_new_hander函数来定义内存分配异常的处理</font>
										</p>
										<p>
												<font size="4">十五、Ｃ++的特性<br />Ｃ++新增加有重载(overload)，内联（inline），Const，Virtual四种机制<br />重载和内联：即可用于全局函数，也可用于类的成员函数；<br />Const和Virtual：只可用于类的成员函数；<br />重载：在同一类中，函数名相同的函数。由不同的参数决定调用那个函数。函数可要不可要Virtual关键字。和全局函数同名的函数<br />不叫重载。如果在类中调用同名的全局函数，必须用全局引用符号::引用。<br />覆盖是指派生类函数覆盖基类函数<br />函数名相同；<br />参数相同；<br />基类函数必须有Virtual关键字；<br />不同的范围(派生类和基类)。<br />隐藏是指派生类屏蔽了基类的同名函数相同<br />1、 函数名相同，但参数不同，此时不论基类有无Virtual关键字，基类函数将被隐藏。<br />2、 函数名相同，参数也相同，但基类无Virtual关键字(有就是覆盖)，基类函数将被隐藏。<br />内联：inline关键字必须与定义体放在一起，而不是单单放在声明中。<br />Const：const是constant的缩写，“恒定不变”的意思。被const修饰的东西都受到强制保护，可以预防意外的变动，能提高程序的<br />健壮性。<br />1、 参数做输入用的指针型参数，加上const可防止被意外改动。<br />2、 按值引用的用户类型做输入参数时，最好将按值传递的改为引用传递，并加上const关键字，目的是为了提高效率。数据类型为<br />内部类型的就没必要做这件事情；如：<br />将void Func(A a) 改为void Func(const A &amp;a)。<br />而void func(int a)就没必要改成void func(const int &amp;a);<br />3、 给返回值为指针类型的函数加上const，会使函数返回值不能被修改，赋给的变量也只能是const型变量。如：函<br />数const char*GetString(void); char *str=GetString()将会出错。而const char *str=GetString()将是正确的。<br />4、 Const成员函数是指此函数体内只能调用Const成员变量，提高程序的键壮性。如声明函数 int GetCount(void) const;此函数<br />体内就只<br />能调用Const成员变量。<br />Virtual：虚函数：派生类可以覆盖掉的函数，纯虚函数：只是个空函数，没有函数实现体；</font>
										</p>
										<p>
												<font size="4">十六、extern“C”有什么作用？<br />Extern “C”是由Ｃ＋＋提供的一个连接交换指定符号，用于告诉Ｃ＋＋这段代码是Ｃ函数。这是因为C++编译后库中函数名会变<br />得很长，与C生成的不一致，造成Ｃ＋＋不能直接调用C函数，加上extren “c”后，C++就能直接调用C函数了。<br />Extern “C”主要使用正规DLL函数的引用和导出 和 在C++包含C函数或C头文件时使用。使用时在前面加上extern “c” 关键字即<br />可。</font>
										</p>
										<p>
												<font size="4">十七、构造函数与析构函数<br />派生类的构造函数应在初始化表里调用基类的构造函数；<br />派生类和基类的析构函数应加Virtual关键字。<br />不要小看构造函数和析构函数，其实编起来还是不容易。<br />＃i nclude <iostream.h><br />using namespace std;<br />class Base<br />{<br />public: <br />virtual ~Base() { cout "~Base" endl ; }<br />};<br />class Derived : public Base<br />{<br />public: <br />virtual ~Derived() { cout "~Derived" endl ; }<br />};<br />void main(void)<br />{<br />Base * pB = new Derived; // upcast<br />delete pB;<br />cin.get();<br />}<br />输出结果为：<br />~Derived<br />~Base<br />如果析构函数不为虚，那么输出结果为<br />~Base</iostream.h></font>
										</p>
										<p>
												<font size="4">十八、#IFNDEF/#DEFINE/#ENDIF有什么作用<br />仿止该头文件被重复引用<br />一、＃i nclude “filename.h”和＃i nclude filename.h&gt;的区别<br />＃i nclude “filename.h”是指编译器将从当前工作目录上开始查找此文件<br />＃i nclude filename.h&gt;是指编译器将从标准库目录中开始查找此文件</font>
										</p>
										<p>
												<font size="4">二、头文件的作用<br />加强安全检测<br />通过头文件可能方便地调用库功能，而不必关心其实现方式</font>
										</p>
										<p>
												<font size="4">三、* , &amp;修饰符的位置<br />对于*和&amp;修饰符，为了避免误解，最好将修饰符紧靠变量名</font>
										</p>
										<p>
												<font size="4">四、if语句<br />不要将布尔变量与任何值进行比较，那会很容易出错的。<br />整形变量必须要有类型相同的值进行比较<br />浮点变量最好少比点，就算要比也要有值进行限制<br />指针变量要和NULL进行比较，不要和布尔型和整形比较</font>
										</p>
										<p>
												<font size="4">五、const和#define的比较<br />const有数据类型，#define没有数据类型<br />个别编译器中const可以进行调试，#define不可以进行调试<br />在类中定义常量有两种方式<br />1、 在类在声明常量，但不赋值，在构造函数初始化表中进行赋值；<br />2、 用枚举代替const常量。</font>
										</p>
										<p>
												<font size="4">六、C++函数中值的传递方式<br />有三种方式：值传递(Pass by value)、指针传递(Pass by pointer)、引用传递(Pass by reference)<br />void fun(char c) //pass by value<br />void fun(char *str) //pass by pointer<br />void fun(char &amp;str) //pass by reference<br />如果输入参数是以值传递的话，最好使用引用传递代替，因为引用传递省去了临时对象的构造和析构<br />函数的类型不能省略，就算没有也要加个void</font>
										</p>
										<p>
												<font size="4">七、函数体中的指针或引用常量不能被返回<br />Char *func(void)<br />{<br />char str[]=”Hello Word”;<br />//这个是不能被返回的，因为str是个指定变量，不是一般的值，函数结束后会被注销掉<br />return str; <br />}<br />函数体内的指针变量并不会随着函数的消亡而自动释放</font>
										</p>
										<p>
												<font size="4">八、一个内存拷贝函数的实现体<br />void *memcpy(void *pvTo,const void *pvFrom,size_t size)<br />{<br />assert((pvTo!=NULL)&amp;&amp;(pvFrom!=NULL));<br />byte *pbTo=(byte*)pvTo; //防止地址被改变<br />byte *pbFrom=(byte*)pvFrom;<br />while (size-- &gt;0)<br />pbTo++ = pbForm++;<br />return pvTo;<br />} </font>
										</p>
										<p>
												<font size="4">九、内存的分配方式<br />分配方式有三种，请记住，说不定那天去面试的时候就会有人问你这问题<br />1、 静态存储区，是在程序编译时就已经分配好的，在整个运行期间都存在，如全局变量、常量。<br />2、 栈上分配，函数内的局部变量就是从这分配的，但分配的内存容易有限。<br />3、 堆上分配，也称动态分配，如我们用new,malloc分配内存，用delete,free来释放的内存。</font>
										</p>
										<p>
												<font size="4">十、内存分配的注意事项<br />用new或malloc分配内存时，必须要对此指针赋初值。<br />用delete 或free释放内存后，必须要将指针指向NULL<br />不能修改指向常量的指针数据</font>
										</p>
										<p>
												<font size="4">十一、内容复制与比较<br />//数组……<br />char a[]=”Hello Word!”;<br />char b[10];<br />strcpy(b,a);<br />if (strcmp(a,b)==0)<br />{}<br />//指针……<br />char a[]=”Hello Word!”;<br />char *p;<br />p=new char[strlen(a)+1];<br />strcpy(p,a);<br />if (strcmp(p,a)==0)<br />{}</font>
										</p>
										<p>
												<font size="4">十二、sizeof的问题<br />记住一点，C++无法知道指针所指对象的大小，指针的大小永远为4字节<br />char a[]=”Hello World!”<br />char *p=a;<br />count sizeof(a) end; //12字节<br />count sizeof(p) endl; //4字节<br />而且，在函数中，数组参数退化为指针，所以下面的内容永远输出为4<br />void fun(char a[1000])<br />{<br />count sizeof(a) endl; //输出4而不是1000<br />}</font>
										</p>
										<p>
												<font size="4">十三、关于指针<br />1、 指针创建时必须被初始化<br />2、 指针在free 或delete后必须置为NULL<br />3、 指针的长度都为4字节<br />４、释放内存时，如果是数组指针，必须要释放掉所有的内存，如<br />char *p=new char[100];<br />strcpy(p,”Hello World”);<br />delete []p; //注意前面的［］号<br />p=NULL;<br />５、数组指针的内容不能超过数组指针的最大容易。<br />如:<br />char *p=new char[5];<br />strcpy(p,”Hello World”); //报错 目标容易不够大<br />delete []p; //注意前面的［］号<br />p=NULL;</font>
										</p>
										<p>
												<font size="4">十四、关于malloc/free 和new /delete<br />l malloc/free 是C/C+的内存分配符，new /delete是C++的内存分配符。<br />l 注意：malloc/free是库函数，new/delete是运算符<br />l malloc/free不能执行构造函数与析构函数，而new/delete可以<br />l new/delete不能在C上运行，所以malloc/free不能被淘汰<br />l 两者都必须要成对使用<br />l C++中可以使用_set_new_hander函数来定义内存分配异常的处理</font>
										</p>
										<p>
												<font size="4">十五、Ｃ++的特性<br />Ｃ++新增加有重载(overload)，内联（inline），Const，Virtual四种机制<br />重载和内联：即可用于全局函数，也可用于类的成员函数；<br />Const和Virtual：只可用于类的成员函数；<br />重载：在同一类中，函数名相同的函数。由不同的参数决定调用那个函数。函数可要不可要Virtual关键字。和全局函数同名的函数<br />不叫重载。如果在类中调用同名的全局函数，必须用全局引用符号::引用。<br />覆盖是指派生类函数覆盖基类函数<br />函数名相同；<br />参数相同；<br />基类函数必须有Virtual关键字；<br />不同的范围(派生类和基类)。<br />隐藏是指派生类屏蔽了基类的同名函数相同<br />1、 函数名相同，但参数不同，此时不论基类有无Virtual关键字，基类函数将被隐藏。<br />2、 函数名相同，参数也相同，但基类无Virtual关键字(有就是覆盖)，基类函数将被隐藏。<br />内联：inline关键字必须与定义体放在一起，而不是单单放在声明中。<br />Const：const是constant的缩写，“恒定不变”的意思。被const修饰的东西都受到强制保护，可以预防意外的变动，能提高程序的健壮性。<br />1、 参数做输入用的指针型参数，加上const可防止被意外改动。<br />2、 按值引用的用户类型做输入参数时，最好将按值传递的改为引用传递，并加上const关键字，目的是为了提高效率。数据类型为内部类型<br />的就没必要做这件事情；如：<br />将void Func(A a) 改为void Func(const A &amp;a)。<br />而void func(int a)就没必要改成void func(const int &amp;a);<br />3、 给返回值为指针类型的函数加上const，会使函数返回值不能被修改，赋给的变量也只能是const型变量。如：函<br />数const char*GetString(void); char *str=GetString()将会出错。而const char *str=GetString()将是正确的。<br />4、 Const成员函数是指此函数体内只能调用Const成员变量，提高程序的键壮性。如声明函数 int GetCount(void) const;此函数体内就只能<br />调用Const成员变量。<br />Virtual：虚函数：派生类可以覆盖掉的函数，纯虚函数：只是个空函数，没有函数实现体；</font>
										</p>
										<p>
												<font size="4">十六、extern“C”有什么作用？<br />Extern “C”是由Ｃ＋＋提供的一个连接交换指定符号，用于告诉Ｃ＋＋这段代码是Ｃ函数。这是因为C++编译后库中函数名会变得<br />很长，与C生成的不一致，造成Ｃ＋＋不能直接调用C函数，加上extren “c”后，C++就能直接调用C函数了。<br />Extern “C”主要使用正规DLL函数的引用和导出 和 在C++包含C函数或C头文件时使用。使用时在前面加上extern “c” 关键字即可。</font>
										</p>
										<p>
												<font size="4">十七、构造函数与析构函数<br />派生类的构造函数应在初始化表里调用基类的构造函数；<br />派生类和基类的析构函数应加Virtual关键字。<br />不要小看构造函数和析构函数，其实编起来还是不容易。<br />＃i nclude iostream.h&gt;<br />class Base<br />{<br />public: <br />virtual ~Base() { cout "~Base" endl ; }<br />};<br />class Derived : public Base<br />{<br />public: <br />virtual ~Derived() { cout "~Derived" endl ; }<br />};<br />void main(void)<br />{<br />Base * pB = new Derived; // upcast<br />delete pB;<br />}<br />输出结果为：<br />~Derived<br />~Base<br />如果析构函数不为虚，那么输出结果为<br />~Base</font>
										</p>
										<p>
												<font size="4">十八、#IFNDEF/#DEFINE/#ENDIF有什么作用<br />仿止该头文件被重复引用<br /></font>
										</p>
										<p>
												<font size="4">学习C++必须掌握的概念 <br />一、指针的概念<br />char str[] = “ABCDEFG”;<br />char *pc = str; //pc是指向string str的指针<br />short x = 33; 　<br />short *px = &amp;x; //px是指向short x的指针<br />cout *pc endl; //这条语句将打印字符‘A’<br />pc += 4; //指针向右移动4指向第5个字符<br />cout *pc endl; //这时这条语句将打印字符‘E’<br />pc--; //向左移动指针<br />cout *pc endl; //这时这条语句将打印字符‘D’<br />cout *px + 3 endl; //这条语句打印36因为=33+3<br />在 C 程序中,假设我们已定义了以下的几个变量及函数: int k, tem, *P1, *P2, a[5], f(), *P3(); 以下的设定<br />叙述(Assignment statements)中, 那些有语法上的错误? 并请说明其原因<br />1.P1 = &amp;k;<br />2.P2 = a;<br />3.P3 = f;<br />4.P1 = &amp;a[3];<br />5.P1 = P2;<br />答案:<br />(1) P1 = &amp;k; P1是指针变量, 因此P1表位址,而k表示一般变量,&amp;k表示取出k的位址,故正确.<br />(2) P2 = a; a是数组名称,此时可代表数组存放在内存中的起始位址,而P2为指针变量,故正确.<br />(3) P3 = f; f代表函数的名称,此时代表呼叫函数f,因此含有传回值,而P3为指针变量,故此式有错误.<br />(4) P1 = &amp;a[3];P1表指针变量,代表位址,而&amp;a[3]表取出索引(index)为3的数组元素的位址,故正确.<br />(5) P1 = P2; P1,P2皆为指针变量代表位址,此叙述是指将P2的位址指定给P1,故正确.</font>
										</p>
										<p>
												<font size="4">结构的概念<br />结构是一种类型，它的成员默认是public.<br />struct Student //定义一个结构Student用来存放学生的资料<br />{ <br />int id; //编号<br />char name[30]; //名字<br />}<br />Student s = {555, “Davis, Samuel”}; //初始化Student的实例s<br />cout s.id “ “ s.name endl; //这条将打印“ 555 Davis,Samuel”<br />类的概念我想大家都应该很清楚了，我就不废话了。<br />类的继承的概念<br />class base<br />{<br />private:<br />int a;<br />protected:<br />int b;<br />public:<br />int c;<br />};<br />class sub1:public base {…};<br />class sub2:private base{…};<br />说明在base,sub1,sub2中所能取用的data members各为何.并指出这些data members的access mode(private, protected或public).<br />Ans:<br />class data members access mode<br />base a private<br />b protected<br />c public<br />sub1<br />b protected<br />c public<br />sub2<br />b private<br />c private</font>
										</p>
										<p>
												<font size="4">虚函数和抽象类<br />多态 (polymorphism)<br />面向对象程设计的核心观念之一就是多态--它使一群类似的行为的同名称的方法, 但各对象可依适合自己所需的方式建构此同名动作的实行<br />细节, C++多态的关键在于所谓的虚函数这一类的函数。<br />虚函数(virtual function)<br />透过虚拟函数, 衍生类可重新定义基类的成员函数, 若想在C++程式中建立虚拟函数(然後才能实行多态), 只需利用virtual关键字声明函数即<br />可(如下所示)<br />virtual void Display();<br />虚函数的用处<br />针对共享相同基类的那些对象, 可有较一致的使用态度, 例如, 你可能定义一个名为Shape且带有一 个Draw虚拟成员函数的基类, 然后从它派<br />生了Circle类和Square类, 而且它们各自带有自己的Draw成员函数.从这些类派生建立的每个对象都可呼叫Draw成员函数; 但是编译程式可确<br />保各自应呼叫那个版本的Draw 函数.是基类的还是派生类的。<br />一个例子<br />重要观念: 指向父类的指针也可用来指向子类别<br />＃i nclude iostream.h&gt;<br />class BaseClass<br />{<br />public:<br />virtual void Display( ) { cout 100 "\n"; }<br />};<br />class DerivedClass: public BaseClass<br />{<br />public:<br />virtual void Display( ) { cout 200 "\n"; }<br />};<br />void Print(BaseClass* pbc)<br />{ pbc-&gt;Display( ); }<br />int main( )<br />{ BaseClass* pbc = new BaseClass;<br />DerivedClass* pdc = new DerivedClass;<br />Print(pbc);//显示 100<br />Print(pdc);//显示 200<br />return 0;<br />}<br />V-table (Virtual function table)<br />当C++程式呼叫非虚函数, 采用与C程式呼叫函数所用方式一样的静态绑定来呼叫函数. 但是C++程式 若是透过指向类别的指针来呼叫虚函数<br />时, 编译程式则采用所谓的晚期绑定(late binding)或静态绑定 (static binding)技术来呼叫函数.<br />而C++虚函数用虚函数表(virtual function table), 或称V-表来实作动态绑定, 所谓的V-表是一 个函数指针的阵列, 这是编译程序替每个<br />使用虚函数的类所建制的。<br />纯虚函数 (pure virtual function)<br />一个不仅可被重新定义, 而且必须被重新定义的成员函数就称为纯虚函数, 你只要指定函数一个零值 (更有效说法是一个空指针),就可将虚<br />成员函数转为纯虚成员函数,如以下所示<br />virtual void PrintData() = 0;<br />抽象类 (abstract class)<br />当一个类含有至少一个纯虚函数时, 此类就称为抽象类,而你无法以此类来衍生建立对象.</font>
										</p>
										<p>
												<font size="4">C++ template classes<br />一般的声明及使用 <br />class Collection<br />{ …<br />int A[10]; <br />}<br />Collection object; <br />模板的声明及使用<br />template class T&gt; //注意这里<br />class Collection<br />{ …<br />T A[10]; }// generic declaration<br />Collection int&gt; object; //注意这里<br />Collection char&gt; object; //注意这里 <br /></font>
										</p>
										<p>
												<font size="4">冒泡排序 <br />陀陀木修 发表于2005-5-22 12:23:00<br />1、排序方法<br />　将被排序的记录数组R[1..n]垂直排列，每个记录R[i]看作是重量为R[i].key的气泡。根据轻气泡不能在重气泡之下的原则，从下往<br />上扫描数组R：凡扫描到违反本原则的轻气泡，就使其向上"飘浮"。如此反复进行，直到最后任何两个气泡都是轻者在上，重者在下为止。<br />（1）初始<br />　 R[1..n]为无序区。<br />（2）第一趟扫描<br />　 从无序区底部向上依次比较相邻的两个气泡的重量，若发现轻者在下、重者在上，则交换二者的位置。即依次比较(R[n]，R[n-1])，(R[n-1]，R[n-2])，…，(R[2]，R[1])；对于每对气泡(R[j+1]，R[j])，若R[j+1].key 　第一趟扫描完毕时，"最轻"的气泡就飘浮到该区间的顶部，即关键字最小的记录被放在最高位置R[1]上。<br />（3）第二趟扫描<br />　 扫描R[2..n]。扫描完毕时，"次轻"的气泡飘浮到R[2]的位置上……<br />　最后，经过n-1 趟扫描可得到有序区R[1..n]<br />注意：<br />　 第i趟扫描时，R[1..i-1]和R[i..n]分别为当前的有序区和无序区。扫描仍是从无序区底部向上直至该区顶部。扫描完毕时，该区中最<br />轻气泡飘浮到顶部位置R[i]上，结果是R[1..i]变为新的有序区。<br />2、冒泡排序过程示例<br />　对关键字序列为49 38 65 97 76 13 27 49的文件进行冒泡排序的过程【参见动画演示】<br />3、排序算法<br />（1）分析<br />　因为每一趟排序都使有序区增加了一个气泡，在经过n-1趟排序之后，有序区中就有n-1个气泡，而无序区中气泡的重量总是大于等于<br />有序区中气泡的重量，所以整个冒泡排序过程至多需要进行n-1趟排序。<br />　若在某一趟排序中未发现气泡位置的交换，则说明待排序的无序区中所有气泡均满足轻者在上，重者在下的原则，因此，冒泡排序过程<br />可在此趟排序后终止。为此，在下面给出的算法中，引入一个布尔量exchange，在每趟排序开始前，先将其置为FALSE。若排序过程中发生了交换，则将其置为TRUE。各趟排序结束时检查exchange，若未曾发生过交换则终止算法，不再进行下一趟排序。<br />（2）具体算法<br />void BubbleSort(SeqList R)<br />{ //R（l..n)是待排序的文件，采用自下向上扫描，对R做冒泡排序<br />int i，j；<br />Boolean exchange； //交换标志<br />for(i=1;i exchange=FALSE； //本趟排序开始前，交换标志应为假<br />for(j=n-1;j&gt;=i；j--) //对当前无序区R[i..n]自下向上扫描<br />if(R[j+1].key R[0]=R[j+1]； //R[0]不是哨兵，仅做暂存单元<br />R[j+1]=R[j]；<br />R[j]=R[0]；<br />exchange=TRUE； //发生了交换，故将交换标志置为真<br />}<br />if(!exchange) //本趟排序未发生交换，提前终止算法<br />return；<br />} //endfor(外循环)<br />} //BubbleSort <br />4、算法分析<br />（1）算法的最好时间复杂度<br />　若文件的初始状态是正序的，一趟扫描即可完成排序。所需的关键字比较次数C和记录移动次数M均达到最小值：<br />Cmin=n-1<br />Mmin=0。<br />　冒泡排序最好的时间复杂度为O(n)。<br />（2）算法的最坏时间复杂度<br />　若初始文件是反序的，需要进行n-1趟排序。每趟排序要进行n-i次关键字的比较(1≤i≤n-1)，且每次比较都必须移动记录三次来达到交换记录位置。在这种情况下，比较和移动次数均达到最大值：<br />Cmax=n(n-1)/2=O(n2)<br />Mmax=3n(n-1)/2=O(n2)<br />　冒泡排序的最坏时间复杂度为O(n2)。<br />（3）算法的平均时间复杂度为O(n2)<br />　虽然冒泡排序不一定要进行n-1趟，但由于它的记录移动次数较多，故平均时间性能比直接插入排序要差得多。<br />（4）算法稳定性<br />　冒泡排序是就地排序，且它是稳定的。<br />5、算法改进<br />　上述的冒泡排序还可做如下的改进：<br />(1)记住最后一次交换发生位置lastExchange的冒泡排序<br />　　在每趟扫描中，记住最后一次交换发生的位置lastExchange，（该位置之前的相邻记录均已有序）。下一趟排序开始时，R[1..lastExchange-1]是有序区，R[lastExchange..n]是无序区。这样，一趟排序可能使当前有序区扩充多个记录，从而减少排序的趟数。具体算法【参见习题】。<br />(2) 改变扫描方向的冒泡排序<br />①冒泡排序的不对称性<br />　　能一趟扫描完成排序的情况：<br />　只有最轻的气泡位于R[n]的位置，其余的气泡均已排好序，那么也只需一趟扫描就可以完成排序。<br />【例】对初始关键字序列12，18，42，44，45，67，94，10就仅需一趟扫描。<br />需要n-1趟扫描完成排序情况：<br />　 当只有最重的气泡位于R[1]的位置，其余的气泡均已排好序时，则仍需做n-1趟扫描才能完成排序。<br />【例】对初始关键字序列：94，10，12，18，42，44，45，67就需七趟扫描。<br /><br />②造成不对称性的原因<br />　　每趟扫描仅能使最重气泡"下沉"一个位置，因此使位于顶端的最重气泡下沉到底部时，需做n-1趟扫描。<br />③改进不对称性的方法<br />　在排序过程中交替改变扫描方向，可改进不对称性。具体算法【参见习题】。 <br /><br />C++，这个词在中国大陆的程序员圈子中通常被读做“C加加”，而西方的程序员通常读做“see plus plus”， 它是一种被使用的非常广泛的计算机编程语言。C++是一种静态数据类型检查的，支持多重编程范式的通用程序设计语言。它支持过程序程序设计、数据抽象、面向对象程序设计、泛型程序设计等多种程序设计风格。<br />布贾尼•斯特劳斯特卢普（Bjarne Stroustrup）博士在20世纪80年代发明并实现了C++（最初这种语言被称作“C with Classes”）。一开始C++是作为C语言的增强版出现的，从给C语言增加类开始，不断的增加新特性。虚函数、运算符重载、多重继承、模板、异常、RTTI、名字空间逐渐被加入标准。1998年国际标准组织（ISO）颁布了C++程序设计语言的国际标准ISO/IEC 14882-1998。遗憾的是，由于C++语言过于复杂，以及他经历了长年的演变，直到现在（2004年）只有少数几个完全符合这个标准的编译器出现。<br />另外，就目前学习C++而言，可以认为他是一门独立的语言；他并不依赖C语言，我们可以完全不学C语言，而直接学习C++。根据《C++编程思想》（Thinking in C++）一书所评述的，C++与C的效率往往相差在正负5%之间。所以有人认为在大多数场合C++ 完全可以取代C语言。<br />C++语言发展大概可以分为三个阶段：第一阶段从80年代到1995年。这一阶段C++语言基本上是传统类型上的面向对象语言，并且凭借着接<br />近C语言的效率，在工业界使用的开发语言中占据了相当大份额；第二阶段从1995年到2000年，这一阶段由于STL和后来的Boost等程序库的出<br />现，泛型程序设计在C++中占据了越来越多的比重性。当然，同时由于Java、C#等语言的出现和硬件价格的大规模下降，C++开始逐渐退出用户<br />级程序的开发领域，转向系统级别的程序开发；第三阶段从2000年至今，由于以Loki、MPL等程序库为代表的产生式编程和模板元编程的出<br />现，C++出现了发展历史上又一个新的高峰，这些新技术的出现以及和原有技术的融合，使C++已经成为当今主流程序设计语言中最庞大，最<br />复杂的一员。<br /><br />何为算法？ <br />陀陀木修 发表于2005-5-22 12:09:00<br />不论您在您的生活或工作中是否已经注意到，算法的直接或隐含的存在已经日益增多。算法是软件运算部分功能的基础，它存在于嵌入或<br />非嵌入的系统中间，默默地做着底层的事情。有些计算的功能是显而易见的，因此在编程的过程中算法并不显得很重要，不需要单独去考虑它，例如控制单一的开关，或单一的视窗。而越来越多与物理世界相关的复杂运算，人们并不直接地了解如何去算；那么在编程的过程中就需要对于这些算法进行开发；例如，如何最有效地压缩音乐信号数据，诸如通行的MP3算法；或者手机里面的GSM编解码算法。 <br />计算机硬件的发展的速度之快，在其存储量与运算速度方面都早已超过了人类大脑。但是，却因为大大缺少足够的算法，使人们尚做不出<br />能够充分使用这些硬件的软件，以至于巨大的计算机还模拟不出一个简单蚂蚁的功能。模拟人类就更加遥远，即使是模拟人类的某个单一功能，如，语音对话。 <br />那些已经相对成熟并经常使用的算法，就已经被固化在软件模块里面，甚至半导体芯片之中；可以方便地直接使用而无须重新开发。越是<br />尚未成熟标准化的领域，算法越需要直接去开发，例如语音识别的算法。更有人类与日俱增的观察世界和控制世界的欲望，了解自身、相互沟<br />通、以及提高生活的舒适程度的愿望。而这些新的愿望在刚出现的时候，往往还没有已经固化的算法可供选用，这样就不断产生出对新的算法<br />研发的需求。当然也存在由于商业的考虑而需要‘重新发明车轮’的情况。 <br />任何算法以及软件都是要在一定的硬件系统中运行。一个完整的计算机或嵌入电子装置的功能，都是软、硬件结合的结果。因此系统结构<br />的合理性和算法同样很重要。但是，我们工作室的侧重面是对算法的探讨、研发和设计、实现。对于系统我们仅仅是去优化地选择使用，并不<br />花主要的精力去设计。在一切情况下，对于算法的需求包括未知算法本身的研发，以及已知算法在具体系统中的实现。 <br /><br /><br /></font>
										</p>
										<p>
												<font size="4">可以运用分而治之方法来解决排序问题，该问题是将n 个元素排成非递减顺序。分而治之方法通常用以下的步骤来进行排序算法：若n 为1，算法终止；否则，将这一元素集合分割成两个或更多个子集合，对每一个子集合分别排序，然后将排好序的子集合归并为一个集合。 <br />假设仅将n 个元素的集合分成两个子集合。现在需要确定如何进行子集合的划分。一种可能性就是把前面n- 1个元素放到第一个子集中（称为A），最后一个元素放到第二个子集里（称为B）。按照这种方式对A递归地进行排序。由于B仅含一个元素，所以它已经排序完毕，在A排完序后，只需要用程序2 - 1 0中的函数i n s e r t将A和B合并起来。把这种排序算法与I n s e r t i o n S o r t（见程序2 - 1 5）进行比较，可以发现这种排序算法实际上就是插入排序的递归算法。该算法的复杂性为O (n 2 )。把n 个元素划分成两个子集合的另一种方法是将含有最大值的元素放入B，剩下的放入A中。然后A被递归排序。为了合并排序后的A和B，只需要将B添加到A中即可。假如用函数M a x（见程序1 - 3 1）来找出最大元素，这种排序算法实际上就是S e l e c t i o n S o r t（见程序2 - 7）的递归算法。 <br />假如用冒泡过程（见程序2 - 8）来寻找最大元素并把它移到最右边的位置，这种排序算法就是B u b b l e S o r t（见程序2 - 9）的递归算法。这两种递归排序算法的复杂性均为(n2 )。若一旦发现A已经被排好序就终止对A进行递归分割，则算法的复杂性为O(n2 )（见例2 - 1 6和2 - 1 7）。 <br />上述分割方案将n 个元素分成两个极不平衡的集合A和B。A有n- 1个元素，而B仅含一个元素。下面来看一看采用平衡分割法会发生什么情况： A集合中含有n/k 个元素，B中包含其余的元素。递归地使用分而治之方法对A和B进行排序。然后采用一个被称之为归并（ m e rg e）的过程，将已排好序的A和B合并成一个集合。 <br />例2-5 考虑8个元素，值分别为[ 1 0，4，6，3，8，2，5，7 ]。如果选定k = 2，则[ 1 0 , 4 , 6 , 3 ]和[ 8 , 2 , 5 , 7 ]将被分别独立地排序。结果分别为[ 3 , 4 , 6 , 1 0 ]和[ 2 , 5 , 7 , 8 ]。从两个序列的头部开始归并这两个已排序的序列。元素2比3更小，被移到结果序列；3与5进行比较，3被移入结果序列；4与5比较，4被放入结果序列；5和6比较，.。如果选择k= 4，则序列[ 1 0 , 4 ]和[ 6 , 3 , 8 , 2 , 5 , 7 ]将被排序。排序结果分别为[ 4 , 1 0 ]和[ 2 , 3 , 5 , 6&amp;n </font>
										</p>
										<p>
												<font size="4">
												</font>
										</p>
										<p>
												<font size="4">文章来源：CSDN</font>
										</p>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/54595.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-16 10:52 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/16/54595.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C和C++语言学习总结(一)</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54593.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Mon, 16 Feb 2009 01:27:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54593.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54593.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/16/54593.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54593.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54593.html</trackback:ping><description><![CDATA[
		<br />
		<strong>C和C++语言学习总结(一)</strong>
		<br />知识结构: <br />1、if,for,switch,goto <br />2、#define,const <br />3、文件拷贝的代码,动态生成内存,复合表达式,strcpy,memcpy,sizeof <br />4、函数参数传递,内存分配方式,内存错误表现,malloc与new区别 <br />5、类重载、隐藏与覆盖区别,extern问题,函数参数的缺省<br /><br /><br />值问题,宏代码与内联函数区别 <br />6、构造和析构的次序,String函数定义 <br /><br /><br />具体实现: <br />1、if,for,switch,goto <br />if: <br />bool int float pointer char 变量的使用方法 <br />bool bParam; <br />int iParam; <br />float fParam; <br />int* pParam; <br />char cParam; <br />if(bParam) ,if(!bParam); <br />if(iParam == 0 ),if(iParam != 0 ); <br />if(fParam&gt;= -0.00001 &amp;&amp; fParam &lt;= 0.00001); <br />if(pParam == NULL),if(pParam != NULL); <br />if(cParam == '\0'),if(cParam != '\0'); <br /><br />if/else/return 的使用方法 <br />if(condition) 可以等价为 return (condition?x:y); <br />{ <br />return x; <br />} <br />else <br />{ <br />return y; <br />} <br /><br />for: <br />执行效率问题: <br />int row,col,sum; <br />int a[100][5]; <br />for(row=0;row &lt;100;row++) 效率低于 for(col=0;col &lt;5;col++) <br />{ { <br />for(col=0;col &lt;5;col++) for(row=0;row &lt;100;row++) <br />{ { <br />sum = sum+a[row][col]; sum = sum+a[row][col]; <br />} } <br />} } <br /><br />int i; <br />for(i=0;i &lt;N;i++) 效率低于 if(condition) <br />{ { <br />if(condition) for(i=0;i &lt;N;i++) <br />DoSomething(); DoSomething(); <br />else } <br />DoOtherthing(); else <br />} { <br />for(i=0;i &lt;N;i++) <br />DoOtherthing(); <br />} <br /><br />for (int x=0;x &lt;=N-1;x++) 直观性差于 for (int x=0;x &lt;N;x++) <br /><br />switch: <br />switch(variable) <br />{ <br />case value1: ... <br />break; <br />case value2: ... <br />break; <br />default: ... <br />break; <br />} <br />switch(c)中的c的数据类型可以是int,char,long,unsigned int,bool. <br />variable必须是整数或者强制为整数,由于char实际上是ASCII码,所以也可以. <br />c不可以是double,float,char*. <br /><br />goto: <br />goto主要用于 <br />{... <br />{... <br />{.... <br />goto error; <br />} <br />} <br />} <br /><br />error: <br />... <br /><br /><br />2、#define,const <br />#define和const区别 <br />1、#define C语言 <br />const C语言 C++语言 <br />const常量有数据类型,编译器会进行类型安全检查,而#define没有数据类型, <br />const的常量可以进行调试,但宏常量不能进行调试. <br />2、const的使用方法 <br />在全局定义 const float PI=3.1415926 <br />在类中定义 <br />class A <br />{... <br />A(int size); <br />const int SIZE; <br />}; <br />A::A(int size):SIZE(size) <br />{ <br />... <br />} <br />对参数和函数的定义(const只能修饰输入参数,不能修饰输出参数) <br />const int x=1; 表示x的值是1,在程序中不能改变; <br />const int* x; 表示x代表的地址所指向的内容是不能改变得; <br />int const* x; 与const int* x;的表示的意思一样; <br />int * const x; 表示x代表的地址是不能改变的; <br /><br />当是输入参数时,不需要是void Func(const int i),void Func(const int&amp; i),可以是void Func(int i) <br />因为输入参数采用"值传递"(const int i),由于函数将自动产生临时变量用于复制该参数,该输入参数本来就无需保护,所以不要加const修饰; <br />不用const int&amp; i的原因在于内部数据类型的参数不存在构造、析构的过程,而复制也非常快,"值传递"和"引用传递"的效率几乎相当. <br /><br />当是输入参数时,不需要是void Func(const A a),void Func(A a),可以是void Func(A&amp; a)或void Func(const A&amp; a) <br />不用const A a,A a的原因是函数的效率比较低,因为函数体内将产生A类型的临时对象用于复制参数a,而临时对象的构造、复制和析构过程都需要消耗时间 <br />最好用const A&amp;a的原因是A&amp;a中的a可以被改变,A&amp;a和const A&amp;a的好处在于都不会产生临时对象,效率高; <br /><br />const A Func(const A&amp;a )const的好处 <br />第一个const表示返回的是个内部产生的对象,它不能被修改 <br />const A Func(...) <br />{...} <br />const A a=Func(...);//不能是A a=Func(...); <br />第二个const表示输入的参数是引用传递,函数内部不会产生临时对象,而且这个对象不能被内部修改 <br />第三个const表示此函数内部的所涉及的数据成员不能修改 <br />class Stack <br />{ <br />int m_num; <br />int GetCount(void) const; <br />int Pop(void); <br />} <br />int Stack::GetCount(void) const <br />{ <br />m_num++;//编译错误,企图修改数据成员m_num; <br />Pop();//编译错误,企图调用非const函数 <br />} <br /><br />3、文件拷贝的代码 <br />#include &lt;stdio.h&gt; <br />int main(int argc, char* argv[]) <br />{ <br />printf("Hello World!\n"); <br />FILE* in; <br />FILE* out; <br />in=fopen("d:\\1.txt","rb"); <br />out=fopen("d:\\2.txt","wb"); <br />char ch=fgetc(in); <br />while(!feof(in)) <br />{ <br />fputc(ch,out); <br />ch=fgetc(in); <br />} <br />fclose(in); <br />fclose(out); <br />return 0; <br />} <br /><br />动态生成内存的代码 <br />------------------------------------------ <br />正确代码: <br />void GetMemory(char **p, int num) <br />{ <br />*p = (char *)malloc(sizeof(char) * num); <br />} <br />char* GetMemory2(int num) <br />{ <br />char* p = (char *)malloc(sizeof(char) * num); <br />return p; <br />} <br />------------------------------------------ <br />错误的代码: <br />void GetMemory3(char *p, int num) <br />{ <br />p = (char *)malloc(sizeof(char) * num); <br />} <br /><br />------------------------------------------ <br /><table cellspacing="0" cellpadding="0" width="100%" border="0"><tbody><tr><td class="title" valign="center" align="middle" bgcolor="#f7fcff"><strong>C和C++语言学习总结(一)</strong></td></tr><tr><td class="fbrq" align="middle" bgcolor="#f7fcff" height="30">作者：佚名  来源：中国自学编程网收集整理   发布日期：2008-12-05  </td></tr></tbody></table>void Test(void) <br />{ <br />char *str = NULL; <br />GetMemory(&amp;str, 100); // 注意参数是&amp;str,而不是str <br />strcpy(str, "hello"); <br />cout &lt; &lt; str &lt; &lt; endl; <br />free(str); <br /><br />str=NULL; <br />str=GetMemory2(100); <br />strcpy(str, "hello"); <br />cout &lt; &lt; str &lt; &lt; endl; <br />free(str); <br /><br />str=NULL; <br />GetMemory3(str, 100); // str 仍然为NULL <br />strcpy(str, "hello"); // 运行错误 <br />cout &lt; &lt; str &lt; &lt; endl;//运行错误 <br />free(str);//运行错误 <br />} <br /><br />strcpy代码 <br />char* strcpy(char* strDest,const char* strSrc) <br />{ <br />if(strDest==NULL||strSrc==NULL) return NULL; <br />char* pStr=strDest; <br />while((*strDest++=*strSrc++)!='\0) <br />NULL; <br />return pStr; <br />} <br /><br />复合表达式 <br />d = (a = b + c) + r ; <br />该表达式既求a 值又求d 值.应该拆分为两个独立的语句： <br />a = b + c; <br />d = a + r; <br /><br />if (a &lt; b &lt; c) // a &lt; b &lt; c 是数学表达式而不是程序表达式 <br />并不表示 <br />if ((a &lt;b) &amp;&amp; (b &lt;c)) <br />而是成了令人费解的 <br />if ( (a &lt;b) &lt;c ) <br /><br /><br />memcpy代码 <br />void* memcpy(char* strDest,const char* strSrc,size_t size) <br />{ <br />if(strDest==NULL||strSrc==NULL) return NULL; <br />if(size &lt;=0) return NULL; <br />char* pStr=strDest; <br />while(size--&gt;0) <br />*strDest++=*strSrc++; <br />return pStr; <br />} <br /><br />sizeof: <br />i.在32位操作系统中,基本数据类型 <br />类型 字节长度 <br />char 1 <br />short 2 <br />short int 2 <br />signed short 2 <br />unsigned short 2 <br />int 4 <br />long int 4 <br />signed int 4 <br />unsigned int(unsigned) 4 <br />long 4 <br />unsigned long 4 <br />float 4 <br />double 8 <br />void* 4 (所有指针类型长度都一样)(char*,int*,float*,double*) <br />enum 4 <br /><br />ii.在32位操作系统中,定义或函数中的大小 <br />char a[]="hello"; <br />char b[100]; <br />char *p=a; <br />类型 字节长度 <br />sizeof(a) 6 <br />sizeof(b) 100 <br />sizeof(p) 4 <br /><br />void Func(char a[100]) <br />{ <br />sizeof(a); //4 <br />} <br /><br />#pragma pack(1) <br />struct A <br />{ <br />int i; <br />char j; <br />}; <br />sizeof(A) //5 <br /><br />#pragma pack(1) <br />struct A <br />{ <br />int o; <br />int j; <br />union <br />{ <br />int i[10],j,k; <br />}; <br /><br />}; <br />sizeof(A) //48 <br /><br />#pragma pack(1) <br />struct A <br />{ <br />enum day{monring, moon, aftermoon}; <br />}; <br />sizeof(A) //1 <br />sizeof(A::day) //4 <br /><br /><img src ="http://www.cnitblog.com/guopingleee/aggbug/54593.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-16 09:27 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/16/54593.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>strlen 实现</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/15/54582.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Sun, 15 Feb 2009 10:14:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/15/54582.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54582.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/15/54582.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54582.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54582.html</trackback:ping><description><![CDATA[int   strlen(const   char   *str)   <br />  {   <br />  while(*(str+1))   <br />  i++;   <br />  return   i;   <br />  }   <img src ="http://www.cnitblog.com/guopingleee/aggbug/54582.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-15 18:14 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/15/54582.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>strcpy()、memcpy()、memmove()、memset()的实现</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/15/54581.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Sun, 15 Feb 2009 10:11:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/15/54581.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54581.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/15/54581.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54581.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54581.html</trackback:ping><description><![CDATA[
		<div class="tit">一直想知道内部实现, 现在想看了, 就找了一下.<br />不错.<br /><font style="BACKGROUND-COLOR: #7fffd4">strcpy()、memcpy()、memmove()、memset()的实现</font></div>
		<div class="date"> </div>
		<table style="TABLE-LAYOUT: fixed">
				<tbody>
						<tr>
								<td>
										<div class="cnt" id="blog_text">
												<p>strcpy(), 字符串拷贝.<br />char *strcpy(char *strDest, const char *strSrc)<br />{<br />    assert((strDest!=NULL) &amp;&amp; (strSrc !=NULL));<br />    char *address = strDest;     <br />    while( (*strDest++ = * strSrc++) != '\0') <br />       NULL ; <br />    return address ;       <br />}</p>
												<p>memcpy, 拷贝不重叠的内存块 <br />void *memcpy(void* pvTo, void* pvFrom, size_t size) //byte是java里的变量类型<br />{<br />assert(pvTo != NULL &amp;&amp; pvFrom != NULL);<br />void* pbTo = (byte*)pvTo;<br />void* pbFrom = (byte*)pvFrom;<br />/* 内存块重叠吗？如果重叠，就使用memmove */<br />assert(pbTo&gt;=pbFrom+size || pbFrom&gt;=pbTo+size);<br />while(size--&gt;0)<br />    *pbTo++ == *pbFrom++;<br />return pvTo;<br />}</p>
												<p>void *MemCopy(void *dest,const void *src,size_t count)<br />{<br />    char *pDest=static_cast&lt;char *&gt;(dest);<br />    const char *pSrc=static_cast&lt;const char *&gt;(src);<br />    if( pDest&gt;pSrc &amp;&amp; pDest&lt;pSrc+count )<br />    {<br />        for(size_t i=count-1; i&lt;=0; ++i)<br />        {<br />            pDest[i]=pSrc[i];<br />        }<br />    }<br />    else<br />    {<br />        for(size_t i=0; i&lt;count; ++i)<br />        {<br />             pDest[i]=pSrc[i];<br />        }<br />    }<br />    return pDest;<br />}</p>
												<p>void *Memmove(void *Dst, const void*Src,size_t count)<br />{<br />assert(Dst &amp;&amp; Src);<br />void* pDst = Dst;<br />if (Dst&lt;Src &amp;&amp; (char*)Dst &gt; (char*)Src + count)<br />{<br />while(count--)<br />{<br />   *(char*)Dst = *(char*)Src;<br />   Dst = (char*)Dst + 1;<br />   Src = (char*)Src + 1;<br />}<br />}<br />else<br />{<br />   Dst = (char*)Dst + count - 1;<br />   Src = (char*)Src + count - 1;<br />   while(count--)<br />   {<br />      *(char*)Dst = *(char*)Src;<br />      Dst = (char*)Dst -1 ;<br />      Src = (char*)Src -1 ;<br />   }<br />}<br />return pDst;<br />}</p>
												<p>
														<br />void* memmove(void *dest, const void *src,size_t n) <br />{ <br />    if (n == 0) return 0; <br />    if (dest == NULL) return 0; <br />    if (src == NULL)    return 0; <br />    char *psrc = (char*)src; <br />    char *pdest = (char*)dest; <br />    if((dest &lt;= psrc) || (pdest &gt;= psrc + n)) /*检查是否有重叠问题 */ <br />        { <br />         for(int i=0; i &lt; n; i++) /*正向拷贝*/ <br />          { <br />           *pdest = *psrc; <br />           psrc++; <br />           pdest++; <br />          } <br />        } <br />        else /*反向拷贝*/ <br />        { <br />          psrc += n; <br />          pdest += n; <br />          for(int i=0;i&lt;n;i++) <br />           { <br />            psrc--; <br />            pdest--; <br />            *pdest = *psrc; <br />           } <br />        } <br />   return dest;<br />}</p>
												<p>memset:把buffer所指内存区域的前count个字节设置成字符c</p>
												<p>void * Memset(void* buffer, int c, int count)<br />{<br />char* pvTo=(char*)buffer;<br />assert(buffer != NULL);<br />while(count--&gt;0)<br />*pvTo++=(char)c;<br />return buffer;<br />}</p>
										</div>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/54581.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-15 18:11 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/15/54581.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>工具</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/14/54558.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Sat, 14 Feb 2009 12:00:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/14/54558.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54558.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/14/54558.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54558.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54558.html</trackback:ping><description><![CDATA[HTML 路径<a href="http://www.dreamdu.com/xhtml/"><br /><br />http://www.dreamdu.com/xhtml/</a><img src ="http://www.cnitblog.com/guopingleee/aggbug/54558.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-14 20:00 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/14/54558.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>RS232，RS422，RS485的区别</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/14/54552.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Sat, 14 Feb 2009 08:32:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/14/54552.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54552.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/14/54552.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54552.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54552.html</trackback:ping><description><![CDATA[
		<font face="宋体">
				<br />
				<br />1.RS-232-C是美国电子工业协会EIA（Electronic Industry Association）制定的一种串行物理接口标准。RS是英文“推荐标准”的缩写，232为标识号，C表示修改次数。RS-232-C总线标准设有25条信号线，包括一个主通道和一个辅助通道，在多数情况下主要使用主通道，对于一般双工通信，仅需几条信号线就可实现，如一条发送线、一条接收线及一条地线。RS-232-C标准规定的数据传输速率为每秒50、75、 100、150、300、600、1200、2400、4800、9600、19200波特。<font style="BACKGROUND-COLOR: #7fffd4">RS-232-C标准规定，驱动器允许有2500pF的电容负载，通信距离将受此电容限制，例如，采用150pF/m的通信电缆时，最大通信距离为15m；若每米电缆的电容量减小，通信距离可以增加。传输距离短的另一原因是RS-232属单端信号传送，存在共地噪声和不能抑制共模干扰等问题，因此一般用于20m以内的通信。 <br /></font><br /><br />2.RS-485总线,在要求通信距离为几十米到上千米时，广泛采用RS-485 串行总线标准。RS-485采用平衡发送和差分接收，因此具有抑制共模干扰的能力。加上总线收发器具有高灵敏度，能检测低至200mV的电压，故传输信号能在千米以外得到恢复。<font style="BACKGROUND-COLOR: #ee82ee"> RS-485采用半双工工作方式，任何时候只能有一点处于发送状态，因此，发送电路须由使能信号加以控制。RS-485用于多点互连时非常方便，可以省掉许多信号线。应用RS-485 可以联网构成分布式系统，其允许最多并联32台驱动器和32台接收器。 <br /></font><br />3.RS422总线,RS485和RS422电路原理基本相同，都是以差动方式发送和接受，不需要数字地线。差动工作是同速率条件下传输距离远的根本原因，这正是二者与RS232的根本区别，因为RS232是单端输入输出，双工工作时至少需要数字地线 发送线和接受线三条线（异步传输），还可以加其它控制线完成同步等功能。RS422通过两对双绞线可以全双工工作收发互不影响，而RS485只能半双工工作，发收不能同时进行，但它只需要一对双绞线。RS422和RS485在19kpbs下能传输1200米。用新型收发器线路上可连接台设备。  <br /><br />以往，PC与智能设备通讯多借助RS232、RS485、以太网等方式，主要取决于设备的接口规范。但RS232、RS485只能代表通讯的物理介质层和链路层，如果要实现数据的双向访问，就必须自己编写通讯应用程序，但这种程序多数都不能符合ISO/OSI的规范，只能实现较单一的功能，适用于单一设备类型，程序不具备通用性。在RS232或RS485设备联成的设备网中，如果设备数量超过2台，就必须使用RS485做通讯介质，RS485网的设备间要想互通信息只有通过“主（Master）”设备中转才能实现，这个主设备通常是PC，而这种设备网中只允许存在一个主设备，其余全部是从（Slave）设备。而现场总线技术是以ISO/OSI模型为基础的，具有完整的软件支持系统，能够解决总线控制、冲突检测、链路维护等问题。现场总线设备自动成网，无主/从设备之分或允许多主存在。在同一个层次上不同厂家的产品可以互换，设备之间具有互操作性。</font>
		<font color="#ff0000">欢迎进入<a href="http://www.mcu123.net/bbs/" _target="_blank">超前MCU技术论坛</a>对 RS232，RS422，RS485的区别进行讨论! </font>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/54552.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-14 16:32 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/14/54552.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>有关RS232和RS485接口的问答 什么是RS-232-C接口 什么是RS-485接口</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/14/54553.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Sat, 14 Feb 2009 08:32:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/14/54553.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54553.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/14/54553.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54553.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54553.html</trackback:ping><description><![CDATA[RS232与RS485是两个难搞清的东西，尽管它们非常不同。<br /><strong>1.什么是RS-232-C接口？采用RS-232-C接口有何特点？传输电缆长度如何考虑？</strong><br />答：计算机与计算机或计算机与终端之间的数据传送可以采用串行通讯和并行通讯二种方式。由于串行通讯方式具有使用线路少、成本低，特别是在远程传输时，避免了多条线路特性的不一致而被广泛采用。 在串行通讯时，要求通讯双方都采用一个标准接口，使不同 的设备可以方便地连接起来进行通讯。 RS- 232-C接口（又称 EIA RS-232-C）是目前最常用的一种串行通讯接口。它是在1970年由美国电子工业协会（EIA）联合贝尔系统、 调制解调器厂家及计算机终端生产厂家共同制定的用于串行通讯的标 准。它的全名是“数据终端设备（DTE）和数据通讯设备（DCE）之间 串行二进制数据交换接口技术标准”该标准规定采用一个25个脚的 DB25连接器，对连接器的每个引脚的信号内容加以规定，还对各种信 号的电平加以规定。 <br />（1）接口的信号内容 实际上RS-232-C的25条引线中有许多是很少使用的，在计算机与终端通讯中一般只使用3-9条引线。RS-232-C最常用的9条引线的信号内容见附表1所示 <br />（2）接口的电气特性 在RS-232-C中任何一条信号线的电压均为负逻辑关系。即：逻 辑“1”，-5— -15V；逻辑“0” +5— +15V 。噪声容限为2V。即 要求接收器能识别低至+3V的信号作为逻辑“0”，高到-3V的信号 作为逻辑“1” <br /><img height="193" alt="" src="http://www.dz863.com/myimg/uploadimg/20060401/rs232.jpg" width="577" border="0" /><br />(3) 接口的物理结构 RS-232-C接口连接器一般使用型号为DB-25的25芯插头座,通常插头在DCE端,插座在DTE端. 一些设备与PC机连接的RS-232-C接口,因为不使用对方的传送控制信号,只需三条接口线,即“发送数据”、“接收数据”和“信号地”。所以采用DB-9的9芯插头座，传输线采用屏蔽双绞线。 <br />(4) 传输电缆长度 由RS-232C标准规定在码元畸变小于4%的情况下，传输电缆长度应为50英尺，其实这个4%的码元畸变是很保守的，在实际应用中，约有99%的用户是按码元畸变10-20%的范围工作的，所以实际使用中最大距离会远超过50英尺，美国DEC公司曾规定允许码元畸变为 10%而得出附表2 的实验结果。其中1号电缆为屏蔽电缆，型号为DECP.NO.9107723 内有三对双绞线，每对由22# AWG 组成，其外覆以屏蔽网。2号电缆为不带屏蔽的电缆。型号为DECP.NO.9105856-04是22#AWG的四芯电缆。 附表2 DEC 公司的实验结果。 <br /><img height="173" alt="" src="http://www.dz863.com/myimg/uploadimg/20060401/rs485.jpg" width="475" border="0" /><br /><strong>2. 什么是RS-485接口？它比RS-232-C接口相比有何特点？</strong><br /><br />答： 由于RS-232-C接口标准出现较早，难免有不足之处，主要有以下四点： <br />（1） 接口的信号电平值较高，易损坏接口电路的芯片，又因为与TTL 电平不兼容故需使用电平转换电路方能与TTL电路连接。 <br />（2） 传输速率较低，在异步传输时，波特率为20Kbps。 <br />（3） 接口使用一根信号线和一根信号返回线而构成共地的传输形式， 这种共地传输容易产生共模干扰，所以抗噪声干扰性弱。 <br />（4） 传输距离有限，最大传输距离标准值为50英尺，实际上也只能 用在50米左右。 <br />针对RS-232-C的不足，于是就不断出现了一些新的接口标准，RS-485就是其中之一，它具有以下特点： <br />☉ RS-485的电气特性：逻辑“1”以两线间的电压差为+（2—6） V表示；逻辑“0”以两线间的电压差为-（2—6）V表示。接口信号电平比RS-232-C降低了，就不易损坏接口电路的芯片， 且该电平与TTL电平兼容，可方便与TTL 电路连接。 <br />☉ RS-485的数据最高传输速率为10Mbps <br />☉ RS-485接口是采用平衡驱动器和差分接收器的组合，抗共模干能力增强，即抗噪声干扰性好。 <br />☉ RS-485接口的最大传输距离标准值为4000英尺，实际上可达 3000米，另外RS-232-C接口在总线上只允许连接1个收发器， 即单站能力。而RS-485接口在总线上是允许连接多达128个收发器。即具有多站能力,这样用户可以利用单一的RS-485接口方便地建立起设备网络。 <br />因RS-485接口具有良好的抗噪声干扰性，长的传输距离和多站能力等上述优点就使其成为首选的串行接口。 因为RS485接口组成的半双工网络，一般只需二根连线，所以RS485接口均采用屏蔽双绞线传输。 RS485接口连接器采用DB-9的9芯插头座，与智能终端RS485接口采用DB- 9（孔），与键盘连接的键盘接口RS485采用DB-9（针）。 <br />3. 采用RS485接口时，传输电缆的长度如何考虑？ <br />答：在使用RS485接口时，对于特定的传输线经，从发生器到负载其数据信号传输所允许的最大电缆长度是数据信号速率的函数，这个 长度数据主要是受信号失真及噪声等影响所限制。下图所示的最大电缆长度与信号速率的关系曲线是使用24AWG铜芯双绞电话电缆（线 径为0.51mm），线间旁路电容为52.5PF/M，终端负载电阻为100欧 时所得出。（曲线引自GB11014-89附录A）。由图中可知，当数据信 号速率降低到90Kbit/S 以下时，假定最大允许的信号损失为6dBV时， 则电缆长度被限制在1200M。实际上，图中的曲线是很保守的，在实 用时是完全可以取得比它大的电缆长度。 当使用不同线径的电缆。则取得的最大电缆长度是不相同的。例 如：当数据信号速率为600Kbit/S时，采用24AWG电缆，由图可知最 大电缆长度是200m，若采用19AWG电缆（线径为0.91mm）则电缆长 度将可以大于200m； 若采用28AWG 电缆（线径为0。32mm）则电缆 长度只能小于200m。 <img src ="http://www.cnitblog.com/guopingleee/aggbug/54553.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-14 16:32 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/14/54553.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>RS232 通讯原理 ? RS485通讯原理？RS422 是什么？</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/14/54551.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Sat, 14 Feb 2009 08:30:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/14/54551.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54551.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/14/54551.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54551.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54551.html</trackback:ping><description><![CDATA[
		<h1 align="left">RS232 通讯原理 ? RS485通讯原理？RS422 是什么？</h1>
		<h1 align="left">RS485接线的正确原理图 常见的RS485错误接线</h1>
		<p class="unnamed1" align="left">RS-232是串行数据接口标准，最初都是由电子工业协会（EIA）制订并发布的，RS-232在1962年发布，命名为EIA-232-E，作为工业标准，以保证不同厂家产品之间的兼容。RS-422由RS-232发展而来，它是为弥补RS-232之不足而提出的。为改进RS-232通信距离短、速率低的缺点，RS-422定义了一种平衡通信接口，将传输速率提高到10Mb/s，传输距离延长到4000英尺（速率低于100kb/s时），并允许在一条平衡总线上连接最多10个接收器。RS-422是一种单机发送、多机接收的单向、平衡传输规范，被命名为TIA/EIA-422-A标准。为扩展应用范围，EIA又于1983年在RS-422基础上制定了RS-485标准，增加了多点、双向通信能力，即允许多个发送器连接到同一条总线上，同时增加了发送器的驱动能力和冲突保护特性，扩展了总线共模范围，后命名为TIA/EIA-485-A标准。由于EIA提出的建议标准都是以“RS”作为前缀，所以在通讯工业领域，仍然习惯将上述标准以RS作前缀称谓。 <br /><br />备注：以上是官方的专业描述， 看不懂没有关系，大致有个印象就可以了，有兴趣的可以上网可以买一些专业书籍做深入研究，我再用通俗的语言补充描述一下。<br /></p>
		<p class="unnamed1" align="left">
				<strong>RS232通讯的基础知识</strong>：</p>
		<p class="unnamed1" align="left">
				<img height="332" src="http://www.wiegand.com.cn/jisupeixunban/pic/RS232jiexiantu.jpg" width="544" border="1" />
		</p>
		<p class="unnamed1" align="left">RS232通讯又叫串口通讯方式。是指计算机通过RS232国际标准协议用串口连接线和单台设备（控制器）进行通讯的方式。<br /><br />通讯距离：9600波特率下建议在13米以内。<br /><br />通讯速率（波特率 Baud Rate）：缺省常用的是 9600 bps，常见的还有 1200 2400 4800 19200 38400等。波特率越大，传输速度越快，但稳定的传输距离越短，抗干扰能力越差。 </p>
		<p class="unnamed1" align="left">备注：一般台式机会自带1-2个串口插座（公头 （9针插头上带针的俗称公头，带针孔的俗称母头）），现在的笔记本一般不带串口插座，可以购买 USB串口转换器，具体请参考 怎样使用USB串口转换器？</p>
		<p>
				<img height="300" src="http://www.wiegand.com.cn/jisupeixunban/pic/cuankoucazuo.jpg" width="253" />
		</p>
		<table cellspacing="0" cellpadding="0" width="600" border="0">
				<tbody>
						<tr>
								<td>
										<p align="center">
												<img height="343" src="http://www.wiegand.com.cn/jisupeixunban/pic/RS232jiexianduanzixuhao.jpg" width="176" />
										</p>
										<p align="center">
												<strong>公头 接线端子排序图</strong>
										</p>
								</td>
								<td>
										<div align="center">
												<p>
														<img height="343" src="http://www.wiegand.com.cn/jisupeixunban/pic/RS232jiexianduanzixuhao_mu.jpg" width="176" />
												</p>
												<p>
														<strong>母头 接线端子排序图</strong>
												</p>
										</div>
								</td>
						</tr>
				</tbody>
		</table>
		<p> </p>
		<p class="unnamed1" align="left">一般只用 2 3 5 号三根线。</p>
		<p class="unnamed1" align="left">2 RxD Receive Data ，Input <br />3 TxD Transmit Data ，Output<br />5 GND Ground </p>
		<p>
				<img height="300" src="http://www.wiegand.com.cn/jisupeixunban/pic/cuankoulianjiexian.jpg" width="409" />
		</p>
		<p class="unnamed1" align="left">串口连接线： 一般标配是3米以内。</p>
		<p class="unnamed1" align="left">
				<strong>RS485通讯的基本知识</strong>：</p>
		<p class="unnamed1" align="left">RS485和RS232的基本的通讯机理是一致的，他的优点在于弥补了RS232 通讯距离短，不能进行多台设备同时进行联网管理的缺点。</p>
		<p class="unnamed1" align="left">计算机通过 RS232 RS485转换器，依次连接 多台 485设备（门禁控制器），采用轮询的方式，对总线上的设备轮流进行通讯。 </p>
		<p class="unnamed1" align="left">接线标示是 485+ 485- ，分别对应链接设备（控制器）的 485+ 485-。</p>
		<p class="unnamed1" align="left">通讯距离：最远的设备（控制器）到计算机的连线理论上的距离是1200米，建议客户控制在800米以内，能控制在300米以内效果最好。如果距离超长，可以选购 485中继器（延长器）（请向专业的转换器生产公司购买，中继器的放置位置是在总线中间还是开始，请参考相关厂家的说明书。）选购中继器理论上可以延长到 3000米。</p>
		<p class="unnamed1" align="left">负载数量：即一条485总线可以带多少台设备（控制器），这个取决于 控制器的通讯芯片和485转换器的通讯芯片的选型，一般有 32台，64台，128台，256台几种选择，这个是理论的数字，实际应用时，根据现场环境，通讯距离等因素，负载数量达不到指标数。微耕公司控制器和转换器按256台设计，实际建议客户每条总线控制在80台以内。如果有几百上千台控制器，请采用 多串口卡 或者 485HUB来解决，具体 请参考“如果系统控制器数成百上千台，如何组网？”坚决禁止使用无源485转换器，具体请参考“为什么禁止使用无源485转换器？”</p>
		<p class="unnamed1" align="left">485通讯总线（必须用双绞线，或者网线的其中一组），如果用普通的电线（没有双绞）干扰将非常大，通讯不畅，甚至通讯不上。</p>
		<p class="unnamed1" align="left">每台控制器设备必须手牵手地串下去，不可以有星型连接或者分叉。如果有星型连接或者分叉，干扰将非常大，通讯不畅，甚至通讯不上。</p>
		<p>
				<img height="345" src="http://www.wiegand.com.cn/jisupeixunban/pic/RS485lianwantu.jpg" width="736" border="1" />
		</p>
		<p class="unnamed1" align="left">
				<strong>以下是常见的错误的连接方式</strong>：</p>
		<p>
				<img height="374" src="http://www.wiegand.com.cn/jisupeixunban/pic/485cuowu_xinxin.jpg" width="587" border="1" />
		</p>
		<p>
				<img height="422" src="http://www.wiegand.com.cn/jisupeixunban/pic/485cuowu_fenca.jpg" width="545" border="1" />
		</p>
		<p> </p>
		<p class="unnamed1" align="left">
				<strong>RS422通讯基础知识</strong>：</p>
		<p class="unnamed1" align="left">他的通讯原理和RS485类似，区别在于他的总线是两组双绞线（4根线），分别标示为 R+ R- T+ T- .缺点是布线成本高，容易搞错。现在用得比较少了，这里就不详细介绍了。</p>
		<p class="unnamed1" align="left"> </p>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/54551.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-14 16:30 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/14/54551.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>网络流量单位bps与系统单位byte转换</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/14/54550.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Sat, 14 Feb 2009 08:19:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/14/54550.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54550.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/14/54550.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54550.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54550.html</trackback:ping><description><![CDATA[
		<table width="800">
				<tbody>
						<tr>
								<td width="562">
										<div class="STYLE1" align="center">
												<font style="BACKGROUND-COLOR: #7fffd4" color="#0000">注意读书法<br /><br />网络流量单位bps与系统单位byte转换</font>
										</div>
								</td>
								<td width="104">
										<font style="BACKGROUND-COLOR: #7fffd4">
										</font>
								</td>
						</tr>
						<tr>
								<td height="108">
										<p>
												<font style="BACKGROUND-COLOR: #7fffd4">何謂 bps ? 　　bps 是 bits per second 的簡稱。一般資料機及網路通訊的傳輸速率都是以「bps」為單位。如14.4Kbps、28.8Kbps、56Kbps、1.5Mbps 及 10Mbps 等等。 </font>
										</p>
										<p>
												<font style="BACKGROUND-COLOR: #7fffd4">何謂 Bps ? </font>
										</p>
										<p>
												<font style="BACKGROUND-COLOR: #7fffd4">　　即是Byte per second 的簡稱。而電腦一般都以Bps 顯示速度，如1Mbps 大約等同 128 KBps。 </font>
										</p>
										<p>
												<font style="BACKGROUND-COLOR: #7fffd4">何謂 bit ? </font>
										</p>
										<p>
												<font style="BACKGROUND-COLOR: #7fffd4">　　電腦記憶體中最小的單位，在二進位元電腦系統中，每一bit 可以代表0 或 1 的數位訊號。 </font>
										</p>
										<p>
												<font style="BACKGROUND-COLOR: #7fffd4">何謂 Byte ? </font>
										</p>
										<p>
												<font style="BACKGROUND-COLOR: #7fffd4">　　一個Byte由8 bits 所組成，可代表一個字元(A~Z)、數字(0~9)、或符號(,.?!%&amp;+-*/)，是記憶體儲存資料的基本單位，至於每個中文字則須要兩Bytes。當記憶體容量過大時，位元元組這個單位就不夠用，因此就有千位元元組的單位KB出現，以下乃個記憶體計算單位之間的相關性： </font>
										</p>
										<p>
												<font style="BACKGROUND-COLOR: #7fffd4">1 Byte = 8 Bits </font>
										</p>
										<p>
												<font style="BACKGROUND-COLOR: #7fffd4">1 KB = 1024 Bytes </font>
										</p>
										<p>
												<font style="BACKGROUND-COLOR: #7fffd4">1 MB = 1024 KB </font>
										</p>
										<p>
												<font style="BACKGROUND-COLOR: #7fffd4">1 GB = 1024 MB</font>
										</p>
								</td>
								<td class="zw">   网络流量单位是 10Mbps ,而我们在使用windows或下载工具中看到的是1.25MByte/s 。  
<div>   比如安装adsl时使用1Mbps的宽带，在我们使用下载工具中最大使用的速度为1Mbps /8 x 1024=128KByte/s 也就是每秒钟为128K，之所以这样是因为1个字节等于8位，而bps中的这个b表示位，而我们在windows中操作中所接触的单位为字节，所以需要除以8转换为字节。最后在我们接触到网络带宽单位时都要除以8，换算为字节，方便计算。</div><div> </div><div>二进制<br />1 byte (B) = 8 bits (b) 字节=8个二进制位 <br />1 Kilobyte(K/KB)=2^10 bytes=1,024 bytes 千字节 <br />1 Megabyte(M/MB)=2^20 bytes=1,048,576 bytes 兆字节 <br />1 Gigabyte(G/GB)=2^30 bytes=1,073,741,824 bytes 千兆字节 <br />1 Terabyte(T/TB)=2^40 bytes=1,099,511,627,776 bytes吉字节 </div><div> </div><div>十进制 <br />1 byte (B) = 8 bits (b) <br />1 Kilobyte (K / KB) = 10^3 bytes = 1,000 bytes <br />1 Megabyte (M / MB) = 10^6 bytes = 1,000,000 bytes <br />1 Gigabyte (G / GB) = 10^9 bytes = 1,000,000,000 bytes <br />1 Terabyte (T / TB) = 10^12 bytes = 1,000,000,000,000 bytes <br />计算机计量单位和进制计算表 </div></td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<br />
		<br />
		<br />
		<br />
		<br />
		<br />
		<br />
		<br />
		<br />
		<br />什么是kbps？就是1024 bit每秒。正常CD采样率是44.1KHz,每个样本用16bit，立体声是两个声道，那么标准CD是44.1K×16×2=1411.2kbps。mp3采用高压缩保真算法，压缩比率一般是8：1,12：1。也就是一张压缩率是12：1的mp3容量相当于12张CD的容量，mp3的kbps就是CD的八分之一或十二分之一约为192kbps、128kbps。播放的时候通过解码器把192kbps转换成1411.2kbps音频流(实际上肯定达不到)，然后送到耳机。 <br /><br /><br />在计算机/通讯行业中，计算数据传送速度也使用每秒传送公制数据量来计算 <br /><br />1 bit (b) = 0 or 1 = one binary digit 一个二进制位元 <br />1 kilobit(kb)=10^3 bits = 1,000 bits 一千位元 <br />1 Megabit(Mb)=10^6 bits = 1,000,000 bits 一百万位元 <br />1 Gigabit(Gb)=10^9 bits = 1,000,000,000 bits 一万亿位元 <br />根据进制规定，传送速度可以有两种表示方法 bps 和 Bps,但是他们是有严格区别。Bps中的 B 使用的是二进制系统中的Byte字节 ,bps中的 b 是十进制系统中的位元。 <br /><br />在我们常说的56K拨号，100M局域网都是bps计量，当用于软件下载时，下载工具一般又以Bps计算，所以它们之间有 8 bit=1 Byte 的换算关系，那么56Kbps拨号极限下载速度是 56Kbps/8=7KBps 每秒下载7K字节 。 <br /><br />在数据存储，容量计算中，一般又结合公制的进制和二进制的数据计算方法来计算 <br />（二进制） <br /><br />1 byte (B) = 8 bits (b) 字节=8个二进制位 <br />1 Kilobyte(K/KB)=2^10 bytes=1,024 bytes 千字节 <br />1 Megabyte(M/MB)=2^20 bytes=1,048,576 bytes 兆字节 <br />1 Gigabyte(G/GB)=2^30 bytes=1,073,741,824 bytes 千兆字节 <br />1 Terabyte(T/TB)=2^40 bytes=1,099,511,627,776 bytes吉字节 <br />一些存储器厂家特别是硬盘厂家就更紧密结合十进制来计算，这就是为什么操作系统显示的容量与厂家标示的容量有些一些差异的原因 <br />（十进制） <br /><br />1 byte (B) = 8 bits (b) <br />1 Kilobyte (K / KB) = 10^3 bytes = 1,000 bytes <br />1 Megabyte (M / MB) = 10^6 bytes = 1,000,000 bytes <br />1 Gigabyte (G / GB) = 10^9 bytes = 1,000,000,000 bytes <br />1 Terabyte (T / TB) = 10^12 bytes = 1,000,000,000,000 bytes<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><img src ="http://www.cnitblog.com/guopingleee/aggbug/54550.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-14 16:19 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/14/54550.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>"bps"是什么单位?是什么意思?</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/14/54549.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Sat, 14 Feb 2009 08:16:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/14/54549.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54549.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/14/54549.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54549.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54549.html</trackback:ping><description><![CDATA[
		<h1>"bps"是什么单位?是什么意思?</h1>作者：佚名  来源：不详  发布时间：2007-4-25 14:08:57   <br /><br />"bps"是什么单位?是什么意思? "bps"是什么单位?是什么意思? 
<p><strong>回答：</strong></p><p>一知半解<br />级别：大师<br />2006年12月3日bps是bits per second的缩写，一般是指传输速度，表示为: 比特/秒。<br /><br />bps=bits/s=bytes/8s （1Bps每8秒传送1Byte数据）<br /><br />bytes是字节的意思 ，是个大小单位,简写B <br />1GB=1024MB <br />1MB=1024KB <br />1KB=1024B</p><img src ="http://www.cnitblog.com/guopingleee/aggbug/54549.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-14 16:16 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/14/54549.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于如何用mysql_real_connect()连接远程数据库</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/14/54548.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Sat, 14 Feb 2009 04:56:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/14/54548.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54548.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/14/54548.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54548.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54548.html</trackback:ping><description><![CDATA[
		<strong>
				<font color="#295200" size="5">源地址: <a href="http://blog.chinaunix.net/u1/43706/showart_351145.html">http://blog.chinaunix.net/u1/43706/showart_351145.html</a><br />关于如何用mysql_real_connect()连接远程数据库</font>
		</strong>
		<table style="BORDER-COLLAPSE: collapse" bordercolor="#a5bd6b" cellspacing="1" cellpadding="0" width="100%" border="1">
				<tbody>
						<tr>
								<td align="middle">
										<table style="BORDER-COLLAPSE: collapse; WORD-WRAP: break-word" cellspacing="0" cellpadding="0" width="100%" border="0">
												<tbody>
														<tr>
																<td align="middle">
																		<table style="BORDER-COLLAPSE: collapse; WORD-WRAP: break-word" cellspacing="0" cellpadding="0" width="100%" border="0">
																				<tbody>
																						<tr>
																								<td>
																										<div id="art" style="MARGIN: 15px">
																												<div>
																														<font face="NSimsun">    mysql_real_connect()</font>试图建立到运行<code><font face="NSimsun">host</font></code>的一个<strong>MySQL</strong>数据库引擎的一个连接。其函数原形为：</div>
																												<div>
																														<p>
																																<code>
																																		<font face="NSimsun">   MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned int client_flag)</font>
																																</code>    </p>
																												</div>
																												<div>   我要编一段程序用来远程连接一个mysql数据库。我在数据库的本机上做试验，发现mysql_real_connect()的第二个参数设为"localhost"时可以正常连接，当改写为该机器的IP地址"192.168.100.2"时就连接失败。我在程序中写的原句为：</div>
																												<div>mysql_real_connect(mysql,"192.168.100.2","root","","mydns",0,NULL,0)。<br /></div>
																												<div>
																														<br />
																														<br /> </div>
																												<div>   最初，我以为将"localhost"改为"192.168.100.2"之后要将第六个参数端口号写上，但还是不行。由于我是在Linux上做的，所以想也许需要将第七个参数unix_socket写上，结果还是不行。于是到google找解决方法，发现要远程连接mysql需要为mysql的指定帐号设置远程连接的权限。在我的程序中，就要为root设置这一权限。事实证明，我之前连接失败正是由于这个原因导致的。但问题是，网上被广泛转贴的方法是错误的，我照做后还不行，最后问了同学才解决的。下面我具体说一下，望大家不会再被误导。</div>
																												<div> </div>
																												<div>   在mysql数据库中有一个mysql库，它里面包含一个user表，里面存有所有帐号及它们的权限及特征。对应我的user表中找到User项为root的，发现有两项，其Host项分别为localhost和localhost.localdomain。我们只需要把'localhost'改为'%'就可以让所有远程机器以root帐号登陆mysql服务器。也可以将'localhost'改为某一个ip地址，这样就可以在该地址的机器上登陆mysql服务器。这些都没有问题，只是网上被广为传颂的一个更改Host项的方法是错误的。他的方法是用update语句将指定User项的Host项改过来，如果想添加一个新的用于远程访问的帐号，就用insert语句添加。事实是这根本不行，我按照作了，表是变了，但还是连不上。后来经过询问才知道，要想改，结合我的情况，必须用下面的这条语句：</div>
																												<div>     grant all privileges on mydns.* to <a href="mailto:'root'@'%'">'root'@'%'</a>；</div>
																												<div>来改变root帐号的权限。如果添加新帐号也是如此。想必这个表比较特殊，用普通的SQL语句不能操作。如果帐号有密码，后面再加上identified by '***'(*为你帐号的密码)就可以了。</div>
																												<div> </div>
																												<div>   为了解决这个问题用了一下午的时间，费了不少周折，写出来也能让大家少走些弯路。<br /><br /><br />MYSQL *  STDCALL mysql_real_connect(MYSQL *mysql,  //<br />const char *host, //连接主机<br />        const char *user, //数据库用户<br />        const char *passwd, //数据库密码<br />        const char *db, //数据库<br />        unsigned int port,//端口<br />        const char *unix_socket,<br />        unsigned int clientflag);<br /><br />VC一可用的当写汉字到mysql 表里时就看到乱码, 要设字符编码.<br />mysql_options(conn, MYSQL_SET_CHARSET_NAME, "gb2312"); //设字符编码<br />mysql_query(myData,"set names 'gbk'"); 设字符编码<br /><br /></div>
																										</div>
																								</td>
																						</tr>
																				</tbody>
																		</table>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/54548.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-14 12:56 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/14/54548.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC/MFC / 数据库 MySQL</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/13/54527.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Fri, 13 Feb 2009 09:11:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/13/54527.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54527.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/13/54527.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54527.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54527.html</trackback:ping><description><![CDATA[
		<font style="BACKGROUND-COLOR: #ffffff">MySQL数据库专题（一）</font>
		<div class="author">
				<a class="anchor" name="Top">
						<font style="BACKGROUND-COLOR: #ffffff">楼主</font>
				</a>
				<font style="BACKGROUND-COLOR: #ffffff">hnyange（老婆第一最爱，编程我的第二最爱）</font>
				<input class="user4" title="四级用户 该版得分小于等于2000分，大于1000分" type="button" />
				<font style="BACKGROUND-COLOR: #ffffff">2003-05-19 09:25:46 在 VC/MFC / 数据库 提问</font>
		</div>
		<p>
				<font style="BACKGROUND-COLOR: #ffffff">通过VC开发MySQL数据库应用软件有多种方式：   <br />  一、通过MyODBC界面   <br />  二、通过Connector/C++l界面   <br />  三、通过MySQL   C   API界面   <br />  四、第三方封装的MySQL类   <br />    <br />  在经过反复比较，我还是选择了MySQL   C   API方式来进行MySQL的开发。   <br />  在VC中使用MySQL的步骤如下：   <br />    <br />  1、下载MySQL的服务器/客户端安装包   <br />  官方下载地址如下：   <br />  http://www.mysql.com/downloads/mysql-4.0.html   <br />  由于我的开发环境是Windows，所以我下载的是MySQL   for   Windows   V4.0.12   <br />    <br />  2、安装MySQL服务器/客户端包   <br />  一般情况，选择下一步就行了。   <br />  默认情况，MySQL会安装到C:\mysql下。   <br />    <br />  3、在VC中设置其开发环境   <br />  a.设置包含路径为c:\mysql\include   <br />  b.设置引用路径为c:\mysql\include   <br />  c.设置库路径为c:\mysql\lib\debug   <br />  d.设置链接器-输入-附加依赖项为libmySQL.lib   <br />  e.在stdafx.h中加入以下行：   <br />  #include   &lt;winsock.h&gt;   <br />  #include   "mysql.h"   <br />    <br />  4、至此就可以使用C   API函数进行开发了。   <br />    <br />  MySQL提供了很多函数来对数据库进行操作，大致可以分为以下几类：   <br />    <br />  <font color="#0000ff">第一部分   控制类函数   <br />    <br />  mysql_init()初始化MySQL对象   <br /><br /><font color="#ff1493">  mysql_options()设置连接选项    //字符集的转换. 要注意, 当汉字写到mysql时设这个选项 就好了,unsinged int  ret = mysql_options(myData, MYSQL_SET_CHARSET_NAME, "gb2312");  不要设就会写进去乱码.</font><br /><br />  mysql_real_connect()连接到MySQL数据库   <br />    <br />  mysql_real_escape_string()将查询串合法化   <br />  mysql_query()发出一个以空字符结束的查询串   <br />  mysql_real_query()发出一个查询串   <br />    <br />  mysql_store_result()一次性传送结果   <br />  mysql_use_result()逐行传送结果   <br />    <br />  mysql_free_result()释放结果集   <br />    <br />  mysql_change_user()改变用户   <br />  mysql_select_db()改变默认数据库   <br />    <br />  mysql_debug()送出调试信息   <br />  mysql_dump_debug_info()转储调试信息   <br />    <br />  mysql_ping()测试数据库是否处于活动状态   <br />  mysql_shutdown()请求数据库SHUTDOWN   <br />    <br />  mysql_close()关闭数据库连接   <br />    <br />  第二部分   信息获取类函数   <br />  mysql_character_set_name()获取默认字符集   <br />  mysql_get_client_info()获取客户端信息   <br />  mysql_host_info()获取主机信息   <br />  mysql_get_proto_info()获取协议信息   <br />  mysql_get_server_info()获取服务器信息   <br />  mysql_info()获取部分查询语句的附加信息   <br />  mysql_stat()获取数据库状态   <br />    <br />  mysql_list_dbs()获取数据库列表   <br />  mysql_list_tables()获取数据表列表   <br />  mysql_list_fields()获取字段列表   <br />    <br />  第三部分   行列类操作函数   <br />  mysql_field_count()获取字段数   <br />  mysql_affected_rows()获取受影响的行数   <br />  mysql_insert_id()获取AUTO_INCREMENT列的ID值   <br />    <br />  mysql_num_fields()获取结果集中的字段数   <br />  mysql_field_tell()获取当前字段位置   <br />  mysql_field_seek()定位字段   <br />  mysql_fetch_field()获取当前字段   <br />  mysql_fetch_field_direct()获取指定字段   <br />  mysql_frtch_fields()获取所有字段的数组   <br />    <br />    <br />    <br />  mysql_num_rows()获取行数   <br />  mysql_fetch_lengths()获取行长度   <br />  mysql_row_tell()获取当前行位置   <br />  mysql_row_seek()行定位   <br />  mysql_data_seek()行定位   <br />  mysql_fetch_row()获取当前行   <br />    <br />    <br />  第四部分   线程类操作函数   <br />  mysql_list_processes()返回所有线程列表   <br />  mysql_thread_id()获取当前线程ID   <br />  mysql_thread_safe()是否支持线程方式   <br />  mysql_kill()杀列一个线程   <br /></font>    <br />    <br />  第五部分   出错处理类函数   <br />  mysql_errno()获取错误号   <br />  mysql_error()获取错误信息   <br />    <br />  第六部分   已过时的函数   <br />  mysql_connect()   <br />  mysql_create_db()   <br />  mysql_drop_db()   <br />  mysql_eof()   <br />  mysql_reload()   <br />  mysql_escape_string()     <br />    <br />    <br />  以上是我的一点笔记，当然还有操作的标准代码，正在整理中。   <br />  希望大家支持。   <br />  yange@21cn.com </font>
		</p>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/54527.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-13 17:11 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/13/54527.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C/C++ 连接mysql 乱码处理</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/13/54526.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Fri, 13 Feb 2009 08:56:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/13/54526.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54526.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/13/54526.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54526.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54526.html</trackback:ping><description><![CDATA[
		<div class="tit">谢谢他写的, 不然又不知什么时候解决呢.<br /><br /> mysql_set_character_set(myData,"gb2312");  //这个是用在linux 下的, <br />VC6.0下用这个: <font style="BACKGROUND-COLOR: #ffff00">ret = mysql_options(conn, MYSQL_SET_CHARSET_NAME, "gb2312");//来保证你字码, 要加重记住.没这个设置写到数据mysql里就是乱码了, 汉字就是乱码 </font><br /><br />源地址: <a href="http://hi.baidu.com/cuily/blog/item/e38f3ddd397d6f315982dd88.html">http://hi.baidu.com/cuily/blog/item/e38f3ddd397d6f315982dd88.html</a><br /><br />vc6.0连接mysql</div>
		<div class="date">2008年06月22日 星期日 05:06 P.M.</div>
		<table style="TABLE-LAYOUT: fixed">
				<tbody>
						<tr>
								<td>
										<div class="cnt" id="blog_text">
												<p>       周末,闲着的时候突然想起来所谓的数据库编程, 但是具体怎么操作确实全然不知。教学上用postresql，公司里估计是没有用处的吧，所以，就拿mysql来做试验了，哈哈</p>
												<p>      其实，刚开始还是蛮难的，感觉。看网上的例子，就像丈二和尚-----摸不着头脑，突然有种回到了刚开始学习C语言那时候的感觉，什么都不懂，一个简单的编译错误也不想认真看，自己去想，就想找个人问，这个到底是怎么错了？呵呵，所幸，那会没有浮躁。</p>
												<p>    mysql本身带了很多C API，所以操作起来很方便，直接调用API就好了，不过加入相应的库在刚开始就够难为人了，毕竟，这个是我第一次加入外来库。。</p>
												<p>vc6.0添加mysql #include 头文件： 工程-&gt;设置-&gt;C/C++ Y分类那里选择Preprocessor，然后在附加包含路径里写上：C:\Program Files\MySQL\MySQL Server 5.0\include</p>
												<p>就OK 了</p>
												<p>在编写程序时添加进去相应的lib库，使用：#pragma comment(lib, "libmysql.lib")</p>
												<p>.lib 对应的.dll也要拷贝到工程目录下。</p>
												<p>
												</p>
												<p>完整的例子如下：</p>
												<p>#include &lt;iostream&gt;<br />#include &lt;windows.h&gt;<br />#include &lt;cstdlib&gt;<br />#include &lt;cstdio&gt;<br />#include &lt;mysql.h&gt;<br />#pragma comment(lib, "libmysql.lib")<br />using namespace std;</p>
												<p>MYSQL * conn;</p>
												<p>int main()<br />{<br />char     host[] = "localhost";<br />char username[] = "root";<br />char password[] = "123";<br />    char database[] = "school";<br />MYSQL_RES * res_set;<br />MYSQL_ROW row;<br />unsigned int i, ret;<br />MYSQL_FIELD * field;<br />unsigned int num_fields;<br />//mysql_init(MYSQL *)<br />// return values: An initialized MYSQL* handle. <br />//NULL if there was insufficient memory to allocate a new object.     <br />conn = mysql_init(NULL); <br />if(conn != NULL)<br />   ;//cout &lt;&lt; "mysql_init success!" &lt;&lt; endl;<br />else printf("failed !\n");</p>
												<p>
														<font style="BACKGROUND-COLOR: #ffff00">ret = mysql_options(conn, MYSQL_SET_CHARSET_NAME, "gb2312");//来保证你字码, 要加重记住.没这个设置写到数据mysql里就是乱码了, 汉字就是乱码 <br /></font>
														<br />    if(ret == 0)<br />   ;//cout &lt;&lt; "mysql_options success!" &lt;&lt; endl;<br />else printf("failed !\n");</p>
												<p>if(mysql_real_connect(conn, <br />       host, <br />       username, <br />       password, <br />       database, <br />       0, NULL, 0) != NULL)<br />        ;//cout &lt;&lt; "mysql_real_connect success!" &lt;&lt; endl;<br />else printf("failed !\n");<br /><br />//printf("char set %s\n", mysql_character_set_name(conn));<br /><font style="BACKGROUND-COLOR: #7fffd4">mysql_query(conn, "insert into teacher values(7, 'fifth', '插入汉字', '1986-6-6')"); //这到数</font>据里就不是乱码了.<br />printf("insert affect %d sentences\n", mysql_affected_rows(conn));</p>
												<p>if(mysql_query(conn,"SELECT * FROM teacher")) //查询成功返回0    failed here!<br />   printf("mysql_query failed!\n");</p>
												<p>res_set = mysql_store_result(conn);          //失败返回NULL<br />if(res_set == NULL)<br />   printf("res_set is null\n");<br />/*<br />while((field = mysql_fetch_field(res_set)))<br />{<br />   printf("field name %s\n", field-&gt;name);<br />}<br />*/<br />num_fields = mysql_num_fields(res_set);</p>
												<p>for(i = 0; i &lt; num_fields; i++)<br />{<br />   field = mysql_fetch_field_direct(res_set, i);<br />   printf("%s\t\t", field-&gt;name);<br />}<br />printf("\n");</p>
												<p>while ((row = mysql_fetch_row(res_set)) != NULL)<br />{<br />   for (i = 0; i &lt; mysql_num_fields(res_set); i ++)<br />   {<br />    printf("%s\t\t",row[i] != NULL ? row[i] : "NULL");<br />   } <br />   printf("\n");<br />}</p>
												<p>mysql_close(conn);</p>
												<p>return 0;<br />}</p>
												<p>函数我就不详细注释了，在mysql的帮助文档里有详细的注释。</p>
										</div>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/54526.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-13 16:56 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/13/54526.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>五笔帮手</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/06/54313.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Fri, 06 Feb 2009 10:04:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/06/54313.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54313.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/06/54313.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54313.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54313.html</trackback:ping><description><![CDATA[五笔帮手<br /><img src ="http://www.cnitblog.com/guopingleee/aggbug/54313.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-06 18:04 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/06/54313.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C中诸如isdigit</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/06/54311.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Fri, 06 Feb 2009 08:13:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/06/54311.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54311.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/06/54311.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54311.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54311.html</trackback:ping><description><![CDATA[
		<p>看到CSDN首页一篇blog—— 。文中提到的算法暂不议论，单单看回复——一个网友指责楼主使用Char.IsNumber(str,i)的效率不如(r[i]&lt;'0' || str[i]&gt;'9')这种方法高，楼主连声表示认同——真的令我感慨万分，隔行如隔山呀。这话怎么说？C#这种不开源的语言使多少人对其实现产生了误解，我不是说C#程序员对效率算法研究不及C程序员，我是想说开源的ANSI C绝对能使程序员更准确的理解其实现的本质，从而不会错用、误用代码而不自知。</p>
		<p>我对C#实现理解不深，因此我来谈谈C中诸如isdigit(c)、isalpha(c)之类函数的实现，借而推断上述讨论的正确性。</p>
		<p>很多初学者都认为isalnum(c)是这样写的(我最初也是这么人为的)：</p>
		<pre>
				<b>
						<font color="#0000ff">inline</font>
				</b>
				<b>
						<font color="#0000ff"> int</font>
				</b> isdigit<b><font color="#646464">(</font></b><b><font color="#0000ff">char</font></b> c<font color="#646464"><strong>)
{</strong><font color="#0000ff"><strong>   return</strong></font><font color="#000000"> c</font><font color="#646464"><strong>&gt;=</strong></font><font color="#ff00ff">'0'</font><font color="#646464"><strong>&amp;&amp;</strong></font><font color="#000000">c</font><font color="#646464"><strong>&lt;</strong></font><font color="#ff00ff">'9'</font><font color="#646464"><strong>;
}<br /></strong></font><p><strong><br />我当初甚至认为，这种写法已经是非常高效了。直到某一天我开始学习Linux kernel source，我才真正见识了前辈的高效算法，真的眩的令人膛目结舌。下面这段代码摘自Linux 0.11 kernel，大家看看再说:)</strong></p><p><font color="#800080"><strong>0</strong></font><i><font color="#008000"><strong> /*<br />  0  *  linux/lib/ctype.h<br />  0  *<br />  1  *  (C) 1991  Linus Torvalds<br />  2  */</strong></font></i><strong><font color="#800080">  <br />  3<br />  4</font> #define _U<font color="#800080">      0x01</font><i><font color="#008000">    /* upper */</font></i></strong><font color="#800080"><br /><strong>  5</strong></font><strong> #define _L<font color="#800080">      0x02</font><i><font color="#008000">    /* lower */</font></i></strong><font color="#800080"><br /><strong>  6</strong></font><strong> #define _D<font color="#800080">      0x04</font><i><font color="#008000">    /* digit */</font></i></strong><font color="#800080"><br /><strong>  7</strong></font><strong> #define _C<font color="#800080">      0x08</font><i><font color="#008000">    /* cntrl */</font></i></strong><font color="#800080"><br /><strong>  8</strong></font><strong> #define _P<font color="#800080">      0x10</font><i><font color="#008000">    /* punct */</font></i></strong><font color="#800080"><br /><strong>  9</strong></font><strong> #define _S<font color="#800080">      0x20</font><i><font color="#008000">    /* white space (space/lf/tab) */</font></i></strong><font color="#800080"><br /><strong>10</strong></font><strong> #define _X<font color="#800080">      0x40</font><i><font color="#008000">    /* hex digit */</font></i></strong><font color="#800080"><br /><strong>11</strong></font><strong> #define _SP<font color="#800080">     0x80</font><i><font color="#008000">    /* hard space (0x20) */</font></i></strong><font color="#800080"><br /><strong>12 <br />13</strong></font><strong><font color="#0000ff"> extern</font><font color="#0000ff"> unsigned char</font> _ctype<font color="#646464">[];</font></strong><font color="#800080"><br /><strong>14</strong></font><strong><font color="#0000ff"> extern</font><font color="#0000ff"> char</font> _ctmp<font color="#646464">;</font></strong><font color="#800080"><br /><strong>15 <br />16</strong></font><strong> #define isalnum<font color="#646464">(</font>c<font color="#646464">) ((</font>_ctype<font color="#646464">+</font><font color="#800080">1</font><font color="#646464">)[</font>c<font color="#646464">]&amp;(</font>_U<font color="#646464">|</font>_L<font color="#646464">|</font>_D<font color="#646464">))</font></strong><font color="#800080"><br /><strong>17</strong></font><strong> #define isalpha<font color="#646464">(</font>c<font color="#646464">) ((</font>_ctype<font color="#646464">+</font><font color="#800080">1</font><font color="#646464">)[</font>c<font color="#646464">]&amp;(</font>_U<font color="#646464">|</font>_L<font color="#646464">))</font></strong><font color="#800080"><br /><strong>18</strong></font><strong> #define iscntrl<font color="#646464">(</font>c<font color="#646464">) ((</font>_ctype<font color="#646464">+</font><font color="#800080">1</font><font color="#646464">)[</font>c<font color="#646464">]&amp;(</font>_C<font color="#646464">))</font></strong><font color="#800080"><br /><strong>19</strong></font><strong> #define isdigit<font color="#646464">(</font>c<font color="#646464">) ((</font>_ctype<font color="#646464">+</font><font color="#800080">1</font><font color="#646464">)[</font>c<font color="#646464">]&amp;(</font>_D<font color="#646464">))</font></strong><font color="#800080"><br /><strong>20</strong></font><strong> #define isgraph<font color="#646464">(</font>c<font color="#646464">) ((</font>_ctype<font color="#646464">+</font><font color="#800080">1</font><font color="#646464">)[</font>c<font color="#646464">]&amp;(</font>_P<font color="#646464">|</font>_U<font color="#646464">|</font>_L<font color="#646464">|</font>_D<font color="#646464">))</font></strong><font color="#800080"><br /><strong>21</strong></font><strong> #define islower<font color="#646464">(</font>c<font color="#646464">) ((</font>_ctype<font color="#646464">+</font><font color="#800080">1</font><font color="#646464">)[</font>c<font color="#646464">]&amp;(</font>_L<font color="#646464">))</font></strong><font color="#800080"><br /><strong>22</strong></font><strong> #define isprint<font color="#646464">(</font>c<font color="#646464">) ((</font>_ctype<font color="#646464">+</font><font color="#800080">1</font><font color="#646464">)[</font>c<font color="#646464">]&amp;(</font>_P<font color="#646464">|</font>_U<font color="#646464">|</font>_L<font color="#646464">|</font>_D<font color="#646464">|</font>_SP<font color="#646464">))</font></strong><font color="#800080"><br /><strong>23</strong></font><strong> #define ispunct<font color="#646464">(</font>c<font color="#646464">) ((</font>_ctype<font color="#646464">+</font><font color="#800080">1</font><font color="#646464">)[</font>c<font color="#646464">]&amp;(</font>_P<font color="#646464">))</font></strong><font color="#800080"><br /><strong>24</strong></font><strong> #define isspace<font color="#646464">(</font>c<font color="#646464">) ((</font>_ctype<font color="#646464">+</font><font color="#800080">1</font><font color="#646464">)[</font>c<font color="#646464">]&amp;(</font>_S<font color="#646464">))</font></strong><font color="#800080"><br /><strong>25</strong></font><strong> #define isupper<font color="#646464">(</font>c<font color="#646464">) ((</font>_ctype<font color="#646464">+</font><font color="#800080">1</font><font color="#646464">)[</font>c<font color="#646464">]&amp;(</font>_U<font color="#646464">))</font></strong><font color="#800080"><br /><strong>26</strong></font><strong> #define isxdigit<font color="#646464">(</font>c<font color="#646464">) ((</font>_ctype<font color="#646464">+</font><font color="#800080">1</font><font color="#646464">)[</font>c<font color="#646464">]&amp;(</font>_D<font color="#646464">|</font>_X<font color="#646464">))</font></strong><font color="#800080"><br /><strong>27 <br />28</strong></font><strong> #define isascii<font color="#646464">(</font>c<font color="#646464">) (((</font><font color="#0000ff">unsigned</font><font color="#646464">)</font> c<font color="#646464">)&lt;=</font><font color="#800080">0x7f</font><font color="#646464">)</font></strong><font color="#800080"><br /><strong>29</strong></font><strong> #define toascii<font color="#646464">(</font>c<font color="#646464">) (((</font><font color="#0000ff">unsigned</font><font color="#646464">)</font> c<font color="#646464">)&amp;</font><font color="#800080">0x7f</font><font color="#646464">)</font></strong><font color="#800080"><br /><strong>30 <br />31</strong></font><strong> #define tolower<font color="#646464">(</font>c<font color="#646464">) (</font>_ctmp<font color="#646464">=</font>c<font color="#646464">,</font>isupper<font color="#646464">(</font>_ctmp<font color="#646464">)?</font>_ctmp<font color="#646464">-(</font><font color="#ff00ff">'A'</font><font color="#646464">-</font><font color="#ff00ff">'a'</font><font color="#646464">):</font>_ctmp<font color="#646464">)</font></strong><font color="#800080"><br /><strong>32</strong></font><strong> #define toupper<font color="#646464">(</font>c<font color="#646464">) (</font>_ctmp<font color="#646464">=</font>c<font color="#646464">,</font>islower<font color="#646464">(</font>_ctmp<font color="#646464">)?</font>_ctmp<font color="#646464">-(</font><font color="#ff00ff">'a'</font><font color="#646464">-</font><font color="#ff00ff">'A'</font><font color="#646464">):</font>_ctmp<font color="#646464">)</font></strong><font color="#800080"><br /><strong>33 <br />34</strong></font><strong> #endif</strong><font color="#800080"><br /><strong>35 <br /><br />  1</strong></font><i><font color="#008000"><strong> /*<br />  2  *  linux/lib/ctype.c<br />  3  *<br />  4  *  (C) 1991  Linus Torvalds<br />  5  */</strong></font></i><font color="#800080"><br /><strong>  6 <br />  7</strong></font><strong> #include<font color="#646464"> &lt;</font>ctype<font color="#646464">.</font>h<font color="#646464">&gt;</font></strong><font color="#800080"><br /><strong>  8 <br />  9</strong></font><strong><font color="#0000ff"> char</font> _ctmp<font color="#646464">;</font></strong><font color="#800080"><br /><strong>10</strong></font><strong><font color="#0000ff"> unsigned char</font> _ctype<font color="#646464">[] = {</font><font color="#800080">0x00</font><font color="#646464">,</font><i><font color="#008000">                 /* EOF */</font></i></strong><font color="#800080"><br /><strong>11</strong></font><strong> _C<font color="#646464">,</font>_C<font color="#646464">,</font>_C<font color="#646464">,</font>_C<font color="#646464">,</font>_C<font color="#646464">,</font>_C<font color="#646464">,</font>_C<font color="#646464">,</font>_C<font color="#646464">,</font><i><font color="#008000">                        /* 0-7 */</font></i></strong><font color="#800080"><br /><strong>12</strong></font><strong> _C<font color="#646464">,</font>_C<font color="#646464">|</font>_S<font color="#646464">,</font>_C<font color="#646464">|</font>_S<font color="#646464">,</font>_C<font color="#646464">|</font>_S<font color="#646464">,</font>_C<font color="#646464">|</font>_S<font color="#646464">,</font>_C<font color="#646464">|</font>_S<font color="#646464">,</font>_C<font color="#646464">,</font>_C<font color="#646464">,</font><i><font color="#008000">         /* 8-15 */</font></i></strong><font color="#800080"><br /><strong>13</strong></font><strong> _C<font color="#646464">,</font>_C<font color="#646464">,</font>_C<font color="#646464">,</font>_C<font color="#646464">,</font>_C<font color="#646464">,</font>_C<font color="#646464">,</font>_C<font color="#646464">,</font>_C<font color="#646464">,</font><i><font color="#008000">                        /* 16-23 */</font></i></strong><font color="#800080"><br /><strong>14</strong></font><strong> _C<font color="#646464">,</font>_C<font color="#646464">,</font>_C<font color="#646464">,</font>_C<font color="#646464">,</font>_C<font color="#646464">,</font>_C<font color="#646464">,</font>_C<font color="#646464">,</font>_C<font color="#646464">,</font><i><font color="#008000">                        /* 24-31 */</font></i></strong><font color="#800080"><br /><strong>15</strong></font><strong> _S<font color="#646464">|</font>_SP<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font><i><font color="#008000">                    /* 32-39 */</font></i></strong><font color="#800080"><br /><strong>16</strong></font><strong> _P<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font><i><font color="#008000">                        /* 40-47 */</font></i></strong><font color="#800080"><br /><strong>17</strong></font><strong> _D<font color="#646464">,</font>_D<font color="#646464">,</font>_D<font color="#646464">,</font>_D<font color="#646464">,</font>_D<font color="#646464">,</font>_D<font color="#646464">,</font>_D<font color="#646464">,</font>_D<font color="#646464">,</font><i><font color="#008000">                        /* 48-55 */</font></i></strong><font color="#800080"><br /><strong>18</strong></font><strong> _D<font color="#646464">,</font>_D<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font><i><font color="#008000">                        /* 56-63 */</font></i></strong><font color="#800080"><br /><strong>19</strong></font><strong> _P<font color="#646464">,</font>_U<font color="#646464">|</font>_X<font color="#646464">,</font>_U<font color="#646464">|</font>_X<font color="#646464">,</font>_U<font color="#646464">|</font>_X<font color="#646464">,</font>_U<font color="#646464">|</font>_X<font color="#646464">,</font>_U<font color="#646464">|</font>_X<font color="#646464">,</font>_U<font color="#646464">|</font>_X<font color="#646464">,</font>_U<font color="#646464">,</font><i><font color="#008000">      /* 64-71 */</font></i></strong><font color="#800080"><br /><strong>20</strong></font><strong> _U<font color="#646464">,</font>_U<font color="#646464">,</font>_U<font color="#646464">,</font>_U<font color="#646464">,</font>_U<font color="#646464">,</font>_U<font color="#646464">,</font>_U<font color="#646464">,</font>_U<font color="#646464">,</font><i><font color="#008000">                        /* 72-79 */</font></i></strong><font color="#800080"><br /><strong>21</strong></font><strong> _U<font color="#646464">,</font>_U<font color="#646464">,</font>_U<font color="#646464">,</font>_U<font color="#646464">,</font>_U<font color="#646464">,</font>_U<font color="#646464">,</font>_U<font color="#646464">,</font>_U<font color="#646464">,</font><i><font color="#008000">                        /* 80-87 */</font></i></strong><font color="#800080"><br /><strong>22</strong></font><strong> _U<font color="#646464">,</font>_U<font color="#646464">,</font>_U<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font><i><font color="#008000">                        /* 88-95 */</font></i></strong><font color="#800080"><br /><strong>23</strong></font><strong> _P<font color="#646464">,</font>_L<font color="#646464">|</font>_X<font color="#646464">,</font>_L<font color="#646464">|</font>_X<font color="#646464">,</font>_L<font color="#646464">|</font>_X<font color="#646464">,</font>_L<font color="#646464">|</font>_X<font color="#646464">,</font>_L<font color="#646464">|</font>_X<font color="#646464">,</font>_L<font color="#646464">|</font>_X<font color="#646464">,</font>_L<font color="#646464">,</font><i><font color="#008000">      /* 96-103 */</font></i></strong><font color="#800080"><br /><strong>24</strong></font><strong> _L<font color="#646464">,</font>_L<font color="#646464">,</font>_L<font color="#646464">,</font>_L<font color="#646464">,</font>_L<font color="#646464">,</font>_L<font color="#646464">,</font>_L<font color="#646464">,</font>_L<font color="#646464">,</font><i><font color="#008000">                        /* 104-111 */</font></i></strong><font color="#800080"><br /><strong>25</strong></font><strong> _L<font color="#646464">,</font>_L<font color="#646464">,</font>_L<font color="#646464">,</font>_L<font color="#646464">,</font>_L<font color="#646464">,</font>_L<font color="#646464">,</font>_L<font color="#646464">,</font>_L<font color="#646464">,</font><i><font color="#008000">                        /* 112-119 */</font></i></strong><font color="#800080"><br /><strong>26</strong></font><strong> _L<font color="#646464">,</font>_L<font color="#646464">,</font>_L<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font>_P<font color="#646464">,</font>_C<font color="#646464">,</font><i><font color="#008000">                        /* 120-127 */</font></i></strong><font color="#800080"><br /><strong>27 0</strong></font><strong><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><i><font color="#008000">                /* 128-143 */</font></i></strong><font color="#800080"><br /><strong>28 0</strong></font><strong><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><i><font color="#008000">                /* 144-159 */</font></i></strong><font color="#800080"><br /><strong>29 0</strong></font><strong><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><i><font color="#008000">                /* 160-175 */</font></i></strong><font color="#800080"><br /><strong>30 0</strong></font><strong><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><i><font color="#008000">                /* 176-191 */</font></i></strong><font color="#800080"><br /><strong>31 0</strong></font><strong><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><i><font color="#008000">                /* 192-207 */</font></i></strong><font color="#800080"><br /><strong>32 0</strong></font><strong><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><i><font color="#008000">                /* 208-223 */</font></i></strong><font color="#800080"><br /><strong>33 0</strong></font><strong><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><i><font color="#008000">                /* 224-239 */</font></i></strong><font color="#800080"><br /><strong>34 0</strong></font><strong><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">,</font><font color="#800080">0</font><font color="#646464">};</font><i><font color="#008000">               /* 240-255 */</font></i></strong><font color="#800080"><br /><strong>35 <br />36</strong></font><strong><br /></strong></p><p><strong>此一段代码一看便知高下。^_^ </strong></p><p><font color="#ff0000"><strong>我不认为C#的构架师是个笨笨，决计做不出来一个用大家反复调用的底层API函数还不及一段用户组合代码效率高的蠢事来，所以我认为“Char.IsNumber(str,i)的效率不如(r[i]&lt;'0' || str[i]&gt;'9')”绝对是个谬论！</strong></font></p><p> </p><p><strong>-------------<br /><font color="#a52a2a">乾坤一笑 写于2005年1月19日  转载请标明出处和原文链接</font></strong></p><br /><strong>--------------------next---------------------<br />经过刚刚实际测试，VC++6.0&amp;win2k编译环境下，编译器自动去除了inline前缀。所以改用宏的方法测试，得到结果如下。 <br />#define isdigit(c) ((c)&gt;='0'&amp;&amp;(c)&lt;'9') <br />10: bool a=isdigit(c); <br />0040103C movsx eax,byte ptr [ebp-4] <br />00401040 cmp eax,30h <br />00401043 jl main+37h (00401057) <br />00401045 movsx ecx,byte ptr [ebp-4] <br />00401049 cmp ecx,39h <br />0040104C jge main+37h (00401057) <br />0040104E mov dword ptr [ebp-0Ch],1 <br />00401055 jmp main+3Eh (0040105e) <br />00401057 mov dword ptr [ebp-0Ch],0 <br />0040105E mov dl,byte ptr [ebp-0Ch] <br />00401061 mov byte ptr [ebp-8],dl <br /><br />#define isdigit(c) ((_ctype+1)[c]&amp;(_D)) <br />29: bool a=isdigit(c); <br />0040103C movsx eax,byte ptr [ebp-4] <br />00401040 xor ecx,ecx <br />00401042 mov cl,byte ptr _ctype+1 (00422301)[eax] <br />00401048 and ecx,4 <br />0040104B neg ecx <br />0040104D sbb ecx,ecx <br />0040104F neg ecx <br />00401051 mov byte ptr [ebp-8],cl <br /><br />总共节省了三条指令。 <br /><br />实际如果精简代码，则可以达到九条指令的状态，大致如下： <br />#define isdigit(c) ((c)&gt;='0'&amp;&amp;(c)&lt;'9') <br />10: bool a=isdigit(c); <br />0040103C movsx eax,byte ptr [ebp-4] <br />00401040 cmp eax,30h <br />00401043 jl main+37h (00401057) <br />00401049 cmp eax,39h <br />0040104C jge main+37h (00401057) <br />0040104E mov dl,1 <br />00401055 jmp main+3Eh (0040105e) <br />00401057 mov dl,0 <br />00401061 mov byte ptr [ebp-8],dl <br /><br />可以看出，两者效率的差异仅仅在一两条指令上，仅仅是编写小型程序并不值得。不过如果是大规模定义此类宏，又有很多非连续的（例如Hex）。那么后者显然值得这些代价。<br />--------------------next---------------------<br />楼主，我是《判断一个字符串是否全是数字的多种方法及其性能比较（C#实现）》一文的作者，先不说我那篇文章的水平怎么样（其实已经遭到了很多批评），我但就你这篇文章谈一下看法。 <br />首先，C#不是C，而楼主却把两者混为一潭。既然楼主承认“我对C#实现理解不深”，却又怎么敢由“C中诸如isdigit(c)、isalpha(c)之类函数的实现”来推断““Char.IsNumber(str,i)的效率不如(r[i]&lt;'0' || str[i]&gt;'9')”绝对是个谬论！”呢？你怎么知道Char.IsNumber(str,i)是通过调用isdigit(char c)来写的呢？你的猜测错了，根本就不是。我通过Reflactor对Framework进行了反编译，得到了Char.IsNumber的实现（用微软提供的ildasm可以得到IL的代码，结论是一样的）： <br />这是Char.IsNumber(string,int)的实现： <br />public static bool IsNumber(string s, int index) <br />{ <br />if (s == null) <br />{ <br />throw new ArgumentNullException("s"); <br />} <br />if (index &gt;= s.Length) <br />{ <br />throw new ArgumentOutOfRangeException("index"); <br />} <br />return char.IsNumber(s[index]); <br />} <br /><br />被调用的char.IsNumber(char)实现如下： <br />public static bool IsNumber(char c) <br />{ <br />return CharacterInfo.IsNumber(c); <br />} <br /><br />继续追踪，CharacterInfo.IsNumber(c)的实现： <br />public static bool IsNumber(char ch) <br />{ <br />UnicodeCategory category1 = CharacterInfo.GetUnicodeCategory(ch); <br />if ((category1 != UnicodeCategory.DecimalDigitNumber) &amp;&amp; (category1 != UnicodeCategory.LetterNumber)) <br />{ <br />return (category1 == UnicodeCategory.OtherNumber); <br />} <br />return true; <br />} <br /><br />继续，CharacterInfo.GetUnicodeCategory(ch)的实现： <br />public static UnicodeCategory GetUnicodeCategory(char ch) <br />{ <br />return CharacterInfo.InternalGetUnicodeCategory(ch); <br />} <br /><br />还有，CharacterInfo.InternalGetUnicodeCategory(ch)的实现： <br />internal static unsafe UnicodeCategory InternalGetUnicodeCategory(char ch) <br />{ <br />byte num1 = CharacterInfo.m_pDataTable[ch &gt;&gt; 8]; <br />ushort num2 = CharacterInfo.m_pLevel2WordOffset[(num1 &lt;&lt; 4) + ((ch &gt;&gt; 4) &amp; '\x000f')]; <br />byte num3 = CharacterInfo.m_pDataTable[num2 + (ch &amp; '\x000f')]; <br />return (UnicodeCategory) num3; <br />} <br /><br />好了，终于结束了。一个Char.IsNumber(str,i)就是通过上面的一系列调用来实现的，你说效率如何？如果不信可以自己去验证。 <br /><br />Char.IsNumber(str,i)判断的是Unicode字符，而不仅仅是ASCII字符，我在你批判的那篇文章中也提到了，Char.IsNumber(str,i)可以判断全角的１，所以调用是麻烦了一些，不过功能是增加了。可见，楼主的批判是毫无道理的。<br />--------------------next---------------------<br /></strong></font></pre>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/54311.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-06 16:13 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/06/54311.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>哈希表的使用</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/05/54269.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Thu, 05 Feb 2009 02:17:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/05/54269.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54269.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/05/54269.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54269.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54269.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 什么叫哈希表?它主要是用来做什么的?hashtable，音译过来就叫哈希表啊！好像是一种集合类，类似的东西有Vector,LinkList,Map等等，都可以用来存贮对象的集合。只不过哈希表有它自己特殊的功能吧！真正具体有什么特性，还是得看书，我的书放在办公室了，没带下来。还得请教真正的高人。一种映射，存储键和值的对。例如：可以存储电话号码薄：张三、0890870987;李四、004356...&nbsp;&nbsp;<a href='http://www.cnitblog.com/guopingleee/archive/2009/02/05/54269.html'>阅读全文</a><img src ="http://www.cnitblog.com/guopingleee/aggbug/54269.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-05 10:17 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/05/54269.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++移位运算</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/03/54222.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Tue, 03 Feb 2009 08:58:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/03/54222.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54222.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/03/54222.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54222.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54222.html</trackback:ping><description><![CDATA[
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="title" valign="bottom" align="middle" bgcolor="#f7fcff">
										<strong>C++移位运算</strong>
								</td>
						</tr>
						<tr>
								<td class="fbrq" align="middle" bgcolor="#f7fcff">发布日期：2007-10-18 14:04:44  点击:
<script src="/Click.asp?NewsID=07101814053873432"></script>
   <a href="http://forums.zxbc.cn/" target="_blank"><span class="color">进入论坛</span></a></td>
						</tr>
						<tr>
								<td class="comment" bgcolor="#f7fcff">   一个很简单的例子，刚学习编程的朋友应该多看看。 <br />   这段代码可以很方便的输出二进制的方法 <br />#include &lt;iostream&gt; <br />using namespace std; <br />void PrintBinary( const unsigned char val) <br />{ <br /> for (int i=7; i&gt;=0; --i) <br /> { <br />  if (val &amp; (1&lt;&lt;i)) <br />   cout&lt;&lt;"1"; <br />  else <br />   cout&lt;&lt;"0"; <br /> } <br /> return ; <br />} <br />int <br />main(void) <br />{ <br /> PrintBinary(7); <br /> cout&lt;&lt;endl; <br /> return 0; <br />}</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/54222.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-03 16:58 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/03/54222.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C/C++求一个位运算公式</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/03/54221.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Tue, 03 Feb 2009 08:57:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/03/54221.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54221.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/03/54221.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54221.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54221.html</trackback:ping><description><![CDATA[
		<div class="bc0">
				<div class="p90">
						<div class="f14 B wr" id="question_title">
								<cq>C/C++求一个位运算公式</cq>
						</div>
						<div class="wr" id="question_info">
								<span class="red">
										<img height="16" src="http://img.baidu.com/img/iknow/icn_point.gif" width="16" align="absMiddle" /> 悬赏分：20</span> - <span class="gray">解决时间：2008-6-15 21:18</span></div>
						<div class="f14 wr" id="question_content">
								<cd>我需要把一个整数(如1448),分为低八位和高八位(如1448的低八位A8高八位05，这是16位表示，要的是二进制)存入一个段位结构体如 <br />struct data <br />{ <br />unsigned l:8;//低八位 <br />unsigned h:8;//高八位 <br />}; <br />求各位大侠给个位运算的公式，我对位运算实在是不懂，见天看了下书，反而越看越懵，谢谢大家了，我就这20分了 全给你们了。。。</cd>
						</div>
						<div class="f14 wr" id="question_sup">
						</div>
				</div>
				<div class="gray wr" id="question_author" align="right">提问者： <a href="http://passport.baidu.com/?business&amp;aid=6&amp;un=%B7%E7%D6%D0%B1%A9%D7%DF#2" target="_blank">风中暴走</a> - <a href="http://www.baidu.com/search/zhidao_help.html#n5" target="_blank">试用期 一级</a></div>
		</div>
		<div class="rg_4">
		</div>
		<div class="rg_5">
		</div>
		<div class="rg_1">
		</div>
		<div class="mb12 bai">
				<div class="rr_1">
				</div>
				<div class="rr_2">
				</div>
				<div class="rr_3">
				</div>
				<div class="rr">
						<div class="t1">
								<div class="ico">
										<div class="ibest">
										</div>
								</div>最佳答案</div>
						<div class="bc0" style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; PADDING-BOTTOM: 5px; PADDING-TOP: 5px">
								<div class="wr">
										<div class="f14 p90 pl10" id="best_answer_content">
												<ca>struct data d; <br />short s=1448; <br /><br />d.h=(unsigned char)(s&gt;&gt;8); <br />d.l=(unsigned char)s;</ca>
										</div>
										<div class="gray" id="best_answer_info" style="MARGIN: 5px" align="right">回答者：<a href="http://light.baidu.com/" target="_blank"><img title="小桔灯" height="16" alt="小桔灯" src="http://img.baidu.com/img/iknow/icon_lights.gif" width="16" border="0" /></a><a href="http://www.baidu.com/search/zhidao/userelite.html" target="_blank"><img height="18" alt="分类名人" src="http://img.baidu.com/img/iknow/icon_guan.gif" width="18" border="0" /></a><a href="http://passport.baidu.com/?business&amp;aid=6&amp;un=%B8%DF%BD%F0%C9%BD#2" target="_blank">高金山</a> -<a href="http://www.baidu.com/search/zhidao_help.html#n5" target="_blank"> 总监 九级</a><span id="im-user-2c80b8dfbdf0c9bdcb00" title="高金山">  <img style="CURSOR: pointer" onclick="startBaiduHi(&quot;message&quot;,&quot;&quot;,&quot;高金山&quot;,{clk:&quot;icon&quot;,src:&quot;zhidao&quot;,stat:&quot;normal&quot;});return false;" src="http://img.baidu.com/img/iknow/images/offline.gif" align="absBottom" /></span><span id="best_answer_time">6-2 16:29</span></div>
										<div style="MARGIN: 5px; TEXT-ALIGN: right">
												<a href="http://zhidao.baidu.com/remark/55636357.html" target="_blank">我来评论&gt;&gt;</a>
										</div>
										<div class="t2">提问者对于答案的评价：</div>
										<div class="p90 pl10 f14" id="best_answer_comment">谢谢</div>
										<div class="t2">评价已经被关闭    <span class="f12 gray" style="FONT-WEIGHT: normal">目前有 2 个人评价</span></div>
										<div class="pl10">
												<form name="fpj" action="/q" method="post">
														<table cellspacing="0" cellpadding="0" border="0">
																<tbody>
																		<tr valign="top">
																				<input type="hidden" value="22" name="ct" />
																				<input type="hidden" name="mpn" />
																				<input type="hidden" value="100003" name="cm" />
																				<input type="hidden" value="55636357" name="qid" />
																				<input type="hidden" value="iksubmit" name="tn" />
																				<input type="hidden" value="http%3A//zhidao.baidu.com/question/55636357.html" name="lu" />
																				<script><![CDATA[unction g(w){ document.fpj.mpn.value=w;};document.fpj.lu.value=escape(location.href)]]&gt;</script>
																				<td class="f14" width="120">好<br /><span class="red">50%</span> （1）</td>
																				<td class="f14" width="120">不好<br /><span class="grn">50% </span>（1）</td>
																		</tr>
																</tbody>
														</table>
												</form>
										</div>
								</div>
						</div>
				</div>
				<div class="rr_4">
				</div>
				<div class="rr_5">
				</div>
				<div class="rr_1">
				</div>
		</div>
		<a name="irelatelink">
		</a>
		<div class="mb12 bai">
				<div class="rg_1">
				</div>
				<div class="rg_2">
				</div>
				<div class="rg_3">
				</div>
				<div class="rg">
						<div class="t1">
								<div class="ico">
										<div class="irelate">
										</div>
								</div>
						</div>
				</div>
		</div>
		<div class="mb12 bai">
				<div class="rg">
						<div class="t1" style="POSITION: relative"> </div>
						<div class="bc0" style="PADDING-RIGHT: 0pt; PADDING-LEFT: 0pt; PADDING-BOTTOM: 5px; PADDING-TOP: 5px">
								<div class="wr">
										<a name="189209784">
										</a>
										<div class="f14 p90 pl10">
												<span id="reply_content_189209784">
														<cn>struct data d; <br />unsigned short s = 1448; <br /><br />d.h = (unsigned char)(s &gt;&gt; 8); // 高8位 <br />d.l = (unsigned char)(s &amp; 0xff); //低8位</cn>
												</span>
										</div>
								</div>
						</div>
				</div>
		</div>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/54221.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-03 16:57 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/03/54221.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>base64源码</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/03/54218.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Tue, 03 Feb 2009 08:33:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/03/54218.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54218.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/03/54218.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54218.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54218.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 代码有问题请联系, 指出错地址: http://blog.csdn.net/jiadelin/archive/2008/06/19/2566559.aspx源码: #include &lt;stdio.h&gt;#include &lt;string.h&gt;#include &lt;malloc.h&gt;#define BASE64_PAD64 '='char base64_alphabet...&nbsp;&nbsp;<a href='http://www.cnitblog.com/guopingleee/archive/2009/02/03/54218.html'>阅读全文</a><img src ="http://www.cnitblog.com/guopingleee/aggbug/54218.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-03 16:33 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/03/54218.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>base64源程序</title><link>http://www.cnitblog.com/guopingleee/archive/2009/02/03/54202.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Tue, 03 Feb 2009 05:53:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/02/03/54202.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54202.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/02/03/54202.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54202.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54202.html</trackback:ping><description><![CDATA[
		<h1> </h1>
		<h1> </h1>
		<h1>
				<img height="16" alt="原创" src="http://blog.csdn.net/images/authorship.gif" width="15" border="0" /> <a href="http://blog.csdn.net/jiadelin/archive/2008/06/19/2566559.aspx">base64源程序</a><cite class="fav_csdnstylebykimi"><a class="fav_csdnstylebykimi" title="收藏到我的网摘中，并分享给我的朋友" href="javascript:d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(saveit=window.open('http://wz.csdn.net/storeit.aspx?t='+escape(d.title)+'&amp;u='+escape(d.location.href)+'&amp;c='+escape(t),'saveit','scrollbars=no,width=590,height=300,left=75,top=20,status=no,resizable=yes'));saveit.focus();">收藏</a></cite></h1>
		<div class="blogstory">
				<span id="Post.ascx_ViewPost_PreviousAndNextEntriesUp">
						<h3> </h3>
						<h3>重点述:<a href="http://blog.csdn.net/jiadelin/archive/2008/06/18/2559984.aspx"></a></h3>
						<div align="left">
								<span style="FONT-SIZE: 10pt; COLOR: black">定义</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">MIME</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">文档传输的</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">RFC2045</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">定义了</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">BASE64</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">编码。</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">
								</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">简要阐述如下：</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">Base64</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">编码其实是将</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">3</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">个</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">8</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">位字节转换为</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">4</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">个</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">6</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">位字节</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">,( 3*8 = 4*6 = 24 ) </span>
								<span style="FONT-SIZE: 10pt; COLOR: black">这</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">4</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">个六位字节其实仍然是</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">8</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">位</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">,</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">只不过高两位被设置为</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">0. </span>
								<span style="FONT-SIZE: 10pt; COLOR: black">当一个字节只有</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">6</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">位有效时</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">,</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">它的取值空间为</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">0 </span>
								<span style="FONT-SIZE: 10pt; COLOR: black">到</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">2</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">的</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">6</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">次方减</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">1 </span>
								<span style="FONT-SIZE: 10pt; COLOR: black">即</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">63,</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">也就是说被转换的</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">Base64</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">编码的每一个编码的取值空间为</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">(0~63) </span>
								<span style="FONT-SIZE: 10pt; COLOR: black">。</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">
								</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">事实上，</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">0~63</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">之间的</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">ASCII</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">码有许多不可见字符，所以应该再做一个映射，映射表为</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">‘A‘ ~ ‘Z‘ ? ASCII</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">（</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">0 ~ 25</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">）</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">‘a’ ~ ‘z‘ ? ASCII</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">（</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">26 ~ 51</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">）</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">‘0’ ~ ‘9‘ ? ASCII</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">（</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">52 ~ 61</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">）</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">‘+‘ ? ASCII</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">（</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">62</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">）</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">‘/‘ ? ASCII</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">（</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">63</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">）</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">
								</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">这样就可以将</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">3</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">个</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">8</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">位字节，转换为</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">4</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">个可见字符。</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">
								</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">具体的字节拆分方法为：</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">aaaaaabb </span>
								<span style="FONT-SIZE: 10pt; COLOR: black">　</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">ccccdddd </span>
								<span style="FONT-SIZE: 10pt; COLOR: black">　</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">eeffffff </span>
								<span style="FONT-SIZE: 10pt; COLOR: black">字节</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">1</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">　　</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">　字节</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">2 </span>
								<span style="FONT-SIZE: 10pt; COLOR: black">　　字节</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">3 </span>
								<span style="FONT-SIZE: 10pt; COLOR: black">转化为：</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">00aaaaaa 00bbcccc 00ddddee 00ffffff </span>
								<span style="FONT-SIZE: 10pt; COLOR: black">注：上面的三个字节位原文，下面四个字节为</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">Base64</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">编码，其前两位均为</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">0</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">。</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">
								</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">这样拆分的时候，原文的字节数量应该是</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">3</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">的倍数，当这个条件不能满足时，用全零字节补足，转化时</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">Base64</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">编码用</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">=</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">号代替，这就是为什么有些</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">Base64</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">编码以一个或两个等号结束的原因，但等号最多有两个，因为：如果</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">F(origin)</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">代表原文的字节数，</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">F(remain)</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">代表余数，则</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">F(remain) = F(origin) MOD 3 </span>
								<span style="FONT-SIZE: 10pt; COLOR: black">成立。</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">
								</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">所以</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">F(remain)</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">的可能取值为</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">0,1,2. </span>
								<span style="FONT-SIZE: 10pt; COLOR: black">如果设</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">n = [F(origin) – F(remain)] / 3 </span>
								<span style="FONT-SIZE: 10pt; COLOR: black">当</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">F(remain) = 0 </span>
								<span style="FONT-SIZE: 10pt; COLOR: black">时，恰好转换为</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">4*n</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">个字节的</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">Base64</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">编码。</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">
								</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">当</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">F(remain) = 1 </span>
								<span style="FONT-SIZE: 10pt; COLOR: black">时，由于一个原文字节可以拆分为属于两个</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">Base64</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">编码的字节，为了让</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">Base64</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">编码是</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">4</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">的倍数，所以应该为补</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">2</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">个等号。</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">
								</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">当</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">F(remain) = 2 </span>
								<span style="FONT-SIZE: 10pt; COLOR: black">时，由于两个原文字节可以拆分为属于</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">3</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">个</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">Base64</span>
								<span style="FONT-SIZE: 10pt; COLOR: black">编码的字节，同理，应该补上一个等号。</span>
						</div>
						<div align="left">
								<span style="FONT-SIZE: 10pt; COLOR: black">具体实现请查看:</span>
								<br />
						</div>
				</span>
				<script><![CDATA[unction StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}]]&gt;</script>
				<p>#define BASE64_PAD64 '='</p>
				<p>char base64_alphabet[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',                          </p>
				<p>                                            'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',                          </p>
				<p>                                            'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a',                         </p>
				<p>                                             'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',                          </p>
				<p>                                             'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',                          </p>
				<p>                                             't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1',                          </p>
				<p>                                              '2', '3', '4', '5', '6', '7', '8', '9', '+',                          </p>
				<p> '/'}; </p>
				<p>char base64_suffix_map[256] = {     </p>
				<p>                       255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,      </p>
				<p>                       255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,      </p>
				<p>                       255, 255, 255,  62, 255, 255, 255,  63,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61, 255, 255,      </p>
				<p>                       255, 255, 255, 255, 255,  0,   1,    2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,      </p>
				<p>                       15,   16,  17,  18,  19,  20,  21,  22,  23,  24,  25, 255, 255, 255, 255, 255, 255,  26,  27,  28,      </p>
				<p>                       29,   30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,      </p>
				<p>                       49,   50,  51, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,      </p>
				<p>                       255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,      </p>
				<p>                       255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,      </p>
				<p>                       255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,      </p>
				<p>                       255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,      </p>
				<p>                       255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,     </p>
				<p>                        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255</p>
				<p>};</p>
				<p>static char cmove_bits(unsigned char src, unsigned lnum, unsigned rnum) </p>
				<p>{    </p>
				<p>             src &lt;&lt;= lnum;   </p>
				<p>             src &gt;&gt;= rnum;    </p>
				<p>              return src; </p>
				<p>} </p>
				<p>char* base64_encode(const char *data) </p>
				<p>{    </p>
				<p>          char *ret, *retpos;    </p>
				<p>          int n, m, padnum = 0, retsize, dlen = strlen(data);</p>
				<p>          if(dlen == 0) return NULL;</p>
				<p>         /* Account the result buffer size and alloc the memory for it. */   </p>
				<p>          if((dlen % 3) != 0)     padnum = 3 - dlen % 3;   </p>
				<p>          retsize = (dlen + padnum) + ((dlen + padnum) * 1/3) + 1;   </p>
				<p>          if((ret = (char*)malloc(retsize)) == NULL)       return NULL;    </p>
				<p>          retpos = ret;</p>
				<p>          for(m = 0; m &lt; (dlen + padnum); m += 3) </p>
				<p>          { </p>
				<p>                       *(retpos) = base64_alphabet[cmove_bits(*data, 0, 2)];      </p>
				<p>                       if(m == dlen + padnum - 3 &amp;&amp; padnum != 0) </p>
				<p>                      {  /* Whether the last bits-group suffice 24 bits. */           </p>
				<p>                                if(padnum == 1) {   /* 16bit need pad one '='. */              </p>
				<p>                                *(retpos + 1) = base64_alphabet[cmove_bits(*data, 6, 2) + cmove_bits(*(data + 1), 0, 4)];               </p>
				<p>                               *(retpos + 2) = base64_alphabet[cmove_bits(*(data + 1), 4, 2)];               </p>
				<p>                               *(retpos + 3) = BASE64_PAD64;           </p>
				<p>                       } </p>
				<p>                       else if(padnum == 2) </p>
				<p>                      { /* 8bit need pad two'='. */              </p>
				<p>                               *(retpos + 1) = base64_alphabet[cmove_bits(*data, 6, 2)];               </p>
				<p>                                *(retpos + 2) = BASE64_PAD64;              </p>
				<p>                                *(retpos + 3) = BASE64_PAD64;           </p>
				<p>                       }       </p>
				<p>                      else </p>
				<p>                     {  /* 24bit normal. */         </p>
				<p>                                *(retpos + 1) = base64_alphabet[cmove_bits(*data, 6, 2) + cmove_bits(*(data + 1), 0, 4)];          </p>
				<p>                                *(retpos + 2) = base64_alphabet[cmove_bits(*(data + 1), 4, 2) + cmove_bits(*(data + 2), 0, 6)];          </p>
				<p>                                *(retpos + 3) = base64_alphabet[*(data + 2) &amp; 0x3f];       </p>
				<p>                      }</p>
				<p>                    retpos += 4;       </p>
				<p>                    data += 3;    </p>
				<p>         }</p>
				<p>         ret[retsize - 1] =0;</p>
				<p>         return ret; </p>
				<p>}</p>
				<p>char* base64_decode(const char *bdata) </p>
				<p>{    </p>
				<p>     char *ret = NULL, *retpos;    </p>
				<p>     int n, m, padnum = 0, retsize, bdlen = strlen(bdata);</p>
				<p>     if(bdlen == 0) return NULL;    if(bdlen % 4 != 0) return NULL;</p>
				<p>     /* Whether the data have invalid base-64 characters? */   </p>
				<p>    for(m = 0; m &lt; bdlen; ++m)</p>
				<p>    {       </p>
				<p>        if((bdata[m] != BASE64_PAD64) &amp;&amp; (base64_suffix_map[bdata[m]] == 255))         </p>
				<p>        goto LEND;   </p>
				<p>    }</p>
				<p>   /* Account the output size. */    </p>
				<p>    if(bdata[bdlen - 1] ==  '=')  padnum = 1;   </p>
				<p>       if(bdata[bdlen - 1] == '=' &amp;&amp; bdata[bdlen - 2] ==  '=') padnum = 2;   </p>
				<p>          retsize = (bdlen - 4) - (bdlen - 4) / 4 + (3 - padnum) + 1;    </p>
				<p>         ret = (char*)malloc(retsize);    </p>
				<p>         if(ret == NULL)             return NULL;  </p>
				<p>         retpos = ret; </p>
				<p>       /* Begging to decode. */   </p>
				<p>       for(m = 0; m &lt; bdlen; m += 4) </p>
				<p>       {       *retpos = cmove_bits(base64_suffix_map[*bdata], 2, 0) + cmove_bits(base64_suffix_map[*(bdata + 1)], 0, 4);       </p>
				<p>                if(m == bdlen - 4 &amp;&amp; padnum != 0) </p>
				<p>                {  /* Only deal with last four bits. */         </p>
				<p>                           if(padnum == 1)   /* Have one pad characters, only two availability characters. */            </p>
				<p>                           *(retpos + 1) = cmove_bits(base64_suffix_map[*(bdata + 1)], 4, 0) + cmove_bits(base64_suffix_map[*(bdata + 2)], 0, 2);                            retpos += 3 - padnum;       </p>
				<p>                } </p>
				<p>                else </p>
				<p>                {         </p>
				<p>                         *(retpos + 1) = cmove_bits(base64_suffix_map[*(bdata + 1)], 4, 0) + cmove_bits(base64_suffix_map[*(bdata + 2)], 0, 2);                          *(retpos + 2) = cmove_bits(base64_suffix_map[*(bdata + 2)], 6, 0) + base64_suffix_map[*(bdata + 3)];          </p>
				<p>                        retpos += 3;       </p>
				<p>                  }    </p>
				<p>           bdata += 4;    </p>
				<p>         }</p>
				<p>   ret[retsize - 1] = 0;</p>
				<p>   LEND: return ret; </p>
				<p>}</p>
		</div>
		<br />
		<br />
		<br />　6.8 Base64 Content-Transfer-Encoding<br />　　设计Base64内容传输编码是为了描述任意的不需要人为识别的字节序列。编码及解码算法很简单，不过，编码后的数据总是比编码前的数据长33%。Base64与RFC1421中定义的Privacy Enhanced Mail (PEM)是同一个编码方法。<br />　　由US－ASCII中65个字符组成一个子集，使用6位来表示每一个可打印的字符（第65个字符“=”表示要进行特殊的操作）<br />　　注意：这个子集有个很重要的性质，那就是，在任何版本的ISO 646(包括US-ASCII)中，它都被描述成相同的内容。而且，在任何版本的EBCDIC中，子集中的所有字符也都具有相同的描述。其它常用的的编码，如UUENCODE、Macintosh binhex 4.0 [RFC-1741]、base85就没有这些性质，因此就无法满足邮件二进制传输编码的可移植性要求。<br />　　编码时，每次输入24位数据，输出为4个编码字符。将输入的3个8位字节从左到右连续排列，就可以形成24位数据。将这24位看做是4个连续的6位组，每组都可以单独译成一个base64表中的字符。当通过base64编码方式编码一个位流时，必须假定位流为“重要位优先”的顺序。就是说，位流中的第1位应该是第一个字节中的最高位；位流中的第8位应该是第一个字节中的最低位，依此累推。<br />　　用每组(6位)的值来索引64个可打印字符。索引后将得到的字符依次放入输出字符串中。选择表1中的这些字符，是为了能够完备的描述，并且排除在SMTP中有特殊意义的字符(如‘.’、CF、LF)以及在RFC2046中定义的multipart的边界分隔符中有特殊意义的字符(如‘-’)。<br />　　表1：base64字母表<br />　　 Value Encoding Value Encoding Value Encoding Value Encoding<br />　　 0 A 17 R 34 i 51 z<br />　　 1 B 18 S 35 j 52 0<br />　　 2 C 19 T 36 k 53 1<br />　　 3 D 20 U 37 l 54 2<br />　　 4 E 21 V 38 m 55 3<br />　　 5 F 22 W 39 n 56 4<br />　　 6 G 23 X 40 o 57 5<br />　　 7 H 24 Y 41 p 58 6<br />　　 8 I 25 Z 42 q 59 7<br />　　 9 J 26 a 43 r 60 8<br />　　 10 K 27 b 44 s 61 9<br />　　 11 L 28 c 45 t 62 +<br />　　 12 M 29 d 46 u 63 /<br />　　 13 N 30 e 47 v<br />　　 14 O 31 f 48 w (pad) =<br />　　 15 P 32 g 49 x<br />　　 16 Q 33 h 50 y<br />　　编码输出的流必须被描述成一些不大于76字节的行。解码时，必须要忽略换行符及其它所有不存在于表1中的字符。在base64数据中，除表1中字符、换行符、空格之外的字符都可能表示存在传输错误，在某些情况下，可以适当的给出一些警告信息甚至是拒绝信息。<br />　　<br /><font color="#ff1493">如果需要被编码数据的剩余部分不足24位，则要执行特殊的操作。编码量通常在主体（body）结尾部分结束。<br />当输入少于24位时，会在末尾(右侧)添加一些值为0的位，以形成完整的6位组。<br />用“=”来表示数据结尾的填充。因为所有base64的输入都是完整的字节，所以只可能出现如下情况：<br />     (1)最后的编码输入是完整的24位；这时，编码输出的最后一个单元会是完整的4个不为“=”的个字符。<br />     (2)最后的输入是8位；这时，编码输出的最后一个单元是两个编码字符后接两个填充字符“=”。<br />    (3)最后的输入刚好是16位；这时，编码输出的最后一个单元是三个编码字符后接一个填充字符“=”。<br />　　因为“=”是用来填充数据的结尾部分，所以，它的出现意味着可能已经到达数据末尾(但不切断传输)。然而，也可能无法以这种方式进行判断：当传输的字节个数是三的整数倍时，编码中就不会出现“=”。<br />　　在base64编码数据中，要忽略任何不属于base64字母表的字符。</font><br />　　一定要注意，当base64编码直接应用于未经过规范化的文本内容时，要使用恰当的字节做为换行符。特别是在进行base64编码前，必须要将文本换行符转换为CRLF序列。要注意，一件很重要的事情就是：这些操作可以直接由编码器来完成，而不是在一些实现中先进行一个标准化的步骤。<br />　　注释：不用担心multipart实体中的base64编码部分引用到潜在的边界分隔符（boundary delimiter），因为base64编码中没有使用连字符“-”。<br />　　7. Content-ID 头字段<br />　　在构建一个高级别的用户代理时，可能会需要在一个主体（body）中涉及到另一个主体。因此需要用“Content-ID”头字段给主体（body）设置标签。这个字段在语法构成上与“Message-ID”相同：<br />　　id := &amp;quot;Content-ID&amp;quot; &amp;quot;:&amp;quot; msg-id<br />　　 与Message-ID的值一样，Content-ID的值也必须是世界上唯一的。<br />　　 Content-ID的值可以被用来在多处上下文中唯一的确定MIME实体，尤其用于被message/external-body机制所引用的缓存数据。虽然Content-ID头字段通常是可选的，但是对于生成可选的媒体类型“message/external-body”的实现程序来说，它则是必须存在的。这就是说，每一个message/external-body实体（entity）必须有一个Content-ID字段来允许对这些数据的缓存。值得注意的是，Content-ID值在multipart/alternative媒体类型中有特殊的意义。这一点会在RFC2046中关于multipart/alternative的那一节中进行解释。<img src ="http://www.cnitblog.com/guopingleee/aggbug/54202.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-02-03 13:53 <a href="http://www.cnitblog.com/guopingleee/archive/2009/02/03/54202.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>仔细看看代码</title><link>http://www.cnitblog.com/guopingleee/archive/2009/01/30/54063.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Fri, 30 Jan 2009 13:11:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/01/30/54063.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54063.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/01/30/54063.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54063.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54063.html</trackback:ping><description><![CDATA[
		<p>
				<br />仔细看看代码, 有什么问题, 又有什么好处.<br />void main() <br />{ <br />    char    str[7]="abcd";<br />    char *      path="c:\we.c";<br />    char * pstr;</p>
		<p>     pstr = path + strlen(path);<br />    while(pstr &gt; path)<br />    {<br />        pstr --;<br />    }<br />} </p>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/54063.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-01-30 21:11 <a href="http://www.cnitblog.com/guopingleee/archive/2009/01/30/54063.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> 查看文件是否存在 FindFirstFile </title><link>http://www.cnitblog.com/guopingleee/archive/2009/01/30/54061.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Fri, 30 Jan 2009 06:31:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/01/30/54061.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54061.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/01/30/54061.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54061.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54061.html</trackback:ping><description><![CDATA[
		<p>/* c*/</p>
		<p>#include   &lt;windows.h&gt; <br />#include &lt;stdio.h&gt;<br />int <br />main(int   argc,   char   *argv[]) <br />{ <br />    WIN32_FIND_DATA   FindFileData; <br />    HANDLE   hFind; </p>
		<p>    hFind   =   FindFirstFile("tet.c", &amp;FindFileData); </p>
		<p>    if   (hFind == INVALID_HANDLE_VALUE)   <br />    { <br />        printf   ( "Invalid   File   Handle.   Get   Last   Error   reports   %d\n ",   GetLastError   ()); <br />    }   <br />    else   <br />    { <br />        printf   ( "The   first   file   found   is   %s\n ",   FindFileData.cFileName); <br />        FindClose(hFind); <br />    } </p>
		<p>    return   (0); <br />} <br /></p>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/54061.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-01-30 14:31 <a href="http://www.cnitblog.com/guopingleee/archive/2009/01/30/54061.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>stat  文件属性VC下运行</title><link>http://www.cnitblog.com/guopingleee/archive/2009/01/30/54059.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Fri, 30 Jan 2009 06:03:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/01/30/54059.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54059.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/01/30/54059.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54059.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54059.html</trackback:ping><description><![CDATA[
		<p>网上资源真很多, 我都不知为了解决一个问题都要花多长时间, 都快到放弃的心, 可都坚持 , 学习编程都是要一个人去解决问题, 没有人讨论, 也没人去问,  找不到人去问.<br /><br /><a href="http://qq164587043.blog.51cto.com/261469/90413">http://qq164587043.blog.51cto.com/261469/90413</a><br />/************************************************************<br />系统结构 <br />struct stat {<br />        _dev_t st_dev;<br />        _ino_t st_ino;<br />        unsigned short st_mode;<br />        short st_nlink;<br />        short st_uid;<br />        short st_gid;<br />        _dev_t st_rdev;<br />        _off_t st_size;<br />        time_t st_atime;<br />        time_t st_mtime;<br />        time_t st_ctime;<br />        };<br />********************************************************/</p>
		<p>/* @_@求文件属性. 文件大小等   */<br />#include &lt;stdio.h&gt; <br />#include &lt;process.h&gt; <br />#include &lt;fcntl.h&gt; <br /># include &lt;io.h&gt;<br />#include &lt;string.h&gt;<br />#include &lt;stdlib.h&gt;<br />#include &lt;stdarg.h&gt;<br />#include &lt;sys/stat.h&gt;</p>
		<p>#if 0</p>
		<p>long file_size(const char * filename)<br />{<br />    struct stat     st;    </p>
		<p>    if (stat((char * )filename, &amp;st) &lt; 0)<br />        return 0;<br />    return (long)st.st_size;<br />}<br />void main( void ) <br />{ <br />   printf("%d \n", file_size("tet.c")); </p>
		<p>} </p>
		<p>#else </p>
		<p>#include &lt;stdio.h&gt;<br />#include &lt;sys/stat.h&gt;<br />#include &lt;stdlib.h&gt;</p>
		<p>int main()<br />{<br />        struct stat *buf = NULL;<br />        buf = (struct stat *)malloc(sizeof(struct stat));</p>
		<p>        if(stat("tet.c", buf) == -1)<br />        {<br />                perror("stat error!\n");<br />                exit(1);<br />        }</p>
		<p>        printf("file type               :%d\n", buf-&gt;st_mode);<br />        printf("i-node num              :%d\n", buf-&gt;st_ino);<br />        printf("dev num(firstsystem)    :%d\n", buf-&gt;st_dev);<br />        printf("dev num(special)        :%d\n", buf-&gt;st_rdev);<br />        printf("link numbers            :%d\n", buf-&gt;st_nlink);<br />        printf("uid                     :%d\n", buf-&gt;st_uid);<br />        printf("gid                     :%d\n", buf-&gt;st_gid);<br />        printf("uid                     :%d\n", buf-&gt;st_uid);<br />        printf("gid                     :%d\n", buf-&gt;st_gid);<br />        printf("size in bytes           :%d\n", buf-&gt;st_size);<br />        printf("last access time        :%d\n", buf-&gt;st_atime);<br />        printf("last modification time  :%d\n", buf-&gt;st_mtime);<br />        printf("last status change time :%d\n", buf-&gt;st_ctime);</p>
		<p>        return 0;<br />}</p>
		<p>#endif;</p>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/54059.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-01-30 14:03 <a href="http://www.cnitblog.com/guopingleee/archive/2009/01/30/54059.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>#define用法归类收藏</title><link>http://www.cnitblog.com/guopingleee/archive/2009/01/30/54057.html</link><dc:creator>向左向右走</dc:creator><author>向左向右走</author><pubDate>Fri, 30 Jan 2009 04:51:00 GMT</pubDate><guid>http://www.cnitblog.com/guopingleee/archive/2009/01/30/54057.html</guid><wfw:comment>http://www.cnitblog.com/guopingleee/comments/54057.html</wfw:comment><comments>http://www.cnitblog.com/guopingleee/archive/2009/01/30/54057.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/guopingleee/comments/commentRss/54057.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/guopingleee/services/trackbacks/54057.html</trackback:ping><description><![CDATA[
		<a href="http://blog.csdn.net/czsd82/archive/2007/06/07/1642101.aspx">#define用法归类</a>
		<cite class="fav_csdnstylebykimi">
				<a class="fav_csdnstylebykimi" title="收藏到我的网摘中，并分享给我的朋友" href="javascript:d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(saveit=window.open('http://wz.csdn.net/storeit.aspx?t='+escape(d.title)+'&amp;u='+escape(d.location.href)+'&amp;c='+escape(t),'saveit','scrollbars=no,width=590,height=300,left=75,top=20,status=no,resizable=yes'));saveit.focus();">收藏</a>
		</cite>
		<div class="blogstory">
				<p> 常规用法不再介绍，做如下几点说明和介绍</p>
				<p>
						<font color="#ff0000">1. 带参数的宏只完成简单字符替换，之前不做计算实参的工作</font>，如下</p>
				<p> </p>
				<div style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 95%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
						<div>
								<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
								<span style="COLOR: #0000ff">#define</span>
								<span style="COLOR: #000000"> SUM(x,y) x+y</span>
								<span style="COLOR: #000000">
										<br />
										<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
										<br />
										<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #0000ff">int</span>
								<span style="COLOR: #000000"> a</span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000">3</span>
								<span style="COLOR: #000000">,b</span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000">2</span>
								<span style="COLOR: #000000">,c</span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000">1</span>
								<span style="COLOR: #000000">;<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" /></span>
								<span style="COLOR: #0000ff">int</span>
								<span style="COLOR: #000000"> s;<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />s</span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000">SUM(a</span>
								<span style="COLOR: #000000">+</span>
								<span style="COLOR: #000000">b,b)</span>
								<span style="COLOR: #000000">*</span>
								<span style="COLOR: #000000">SUM(c,b)</span>
								<span style="COLOR: #000000">+</span>
								<span style="COLOR: #000000">c;<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" /></span>
						</div>
				</div>
				<p> </p>
				<p>            结果应该是 s=a+b+b*c+b+c=10。</p>
				<p>
						<font color="#ff0000">2. define中的特殊标识符</font>
				</p>
				<div style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 95%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
						<div>
								<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
								<span style="COLOR: #0000ff">#define</span>
								<span style="COLOR: #000000"> Conn(x,y) x##y</span>
								<span style="COLOR: #000000">
										<br />
										<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #0000ff">#define</span>
								<span style="COLOR: #000000"> ToChar(x) #@x</span>
								<span style="COLOR: #000000">
										<br />
										<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #0000ff">#define</span>
								<span style="COLOR: #000000"> ToString(x) #x</span>
								<span style="COLOR: #000000">
										<br />
										<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
										<br />
										<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #0000ff">int</span>
								<span style="COLOR: #000000"> a</span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000">Conn(</span>
								<span style="COLOR: #000000">12</span>
								<span style="COLOR: #000000">,</span>
								<span style="COLOR: #000000">34</span>
								<span style="COLOR: #000000">);<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" /></span>
								<span style="COLOR: #0000ff">char</span>
								<span style="COLOR: #000000"> b</span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000">ToChar(a);<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" /></span>
								<span style="COLOR: #0000ff">char</span>
								<span style="COLOR: #000000"> c[]</span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000">ToString(a);<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" /></span>
						</div>
				</div>
				<p>结果是 a=1234,c='a',c="1234";</p>
				<p>可以看出 ## 是简单的连接符，#@用来给参数加单引号，#用来给参数加双引号即转成字符串。</p>
				<p>更神奇的是</p>
				<div style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 95%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
						<div>
								<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
								<span style="COLOR: #0000ff">#define</span>
								<span style="COLOR: #000000"> x(s) #s</span>
								<span style="COLOR: #000000">
										<br />
								</span>
								<span style="COLOR: #0000ff">   char</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">*</span>
								<span style="COLOR: #000000">s </span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> x(a   b</span>
								<span id="_33_36_Open_Text">
										<span style="COLOR: #008000">/**/</span>
								</span>
								<span style="COLOR: #000000"> c);<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" /></span>
								<span style="COLOR: #0000ff">char</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">*</span>
								<span style="COLOR: #000000">p </span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> x(a\nb);</span>
						</div>
				</div>
				<p>结果是*s="a  b  c",*p="a\\nb"，#s果然很厉害</p>
				<p>
						<font color="#ff0000">3.define的多行定义</font>
						<br />
						<br />define可以替代多行的代码</p>
				<div style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 95%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
						<div>
								<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
								<span style="COLOR: #0000ff">#define</span>
								<span style="COLOR: #000000"> MACRO(arg1, arg2) do { </span>
								<span style="COLOR: #000000">
										<br />
										<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />stmt1; <br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />stmt2; <br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />} </span>
								<span style="COLOR: #0000ff">while</span>
								<span style="COLOR: #000000">(</span>
								<span style="COLOR: #000000">0</span>
								<span style="COLOR: #000000">) </span>
						</div>
				</div>
				<p>关键是要在每一个换行的时候加上一个"\" </p>
				<p>由此联想到了C中的关于字符串的一些默认规则</p>
				<div style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 95%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
						<div>
								<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
								<span style="COLOR: #0000ff">char</span>
								<span style="COLOR: #000000"> s1[]</span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">abc</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">  </span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">efg</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">;<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" /></span>
								<span style="COLOR: #0000ff">char</span>
								<span style="COLOR: #000000"> s2[]</span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">abc</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">
										<br />
										<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">efg</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">;<br /><img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" /></span>
								<span style="COLOR: #0000ff">char</span>
								<span style="COLOR: #000000"> s3[]</span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">ab\</span>
								<span style="COLOR: #000000">
										<br />
										<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #000000">c</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">;</span>
								<span style="COLOR: #000000">
										<br />
										<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #0000ff">char</span>
								<span style="COLOR: #000000"> s4[]</span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">ab</span>
								<span style="COLOR: #000000">
										<br />
										<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #000000">c</span>
								<span style="COLOR: #000000">"</span>
								<span style="COLOR: #000000">;</span>
						</div>
				</div>
				<p>其中只有s4会产生编译错误，s1="abcefg",s2="abcefg",s3="abc"</p>
				<p>
						<font color="#ff0000">4. 宏调用顺序</font>
				</p>
				<div style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: #e6e6e6; PADDING-BOTTOM: 4px; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 95%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: windowtext 0.5pt solid">
						<div>
								<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
								<span style="COLOR: #0000ff">#define</span>
								<span style="COLOR: #000000"> A 3</span>
								<span style="COLOR: #000000">
										<br />
										<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #0000ff">#define</span>
								<span style="COLOR: #000000"> B 4</span>
								<span style="COLOR: #000000">
										<br />
										<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #0000ff">#define</span>
								<span style="COLOR: #000000"> AB 5</span>
								<span style="COLOR: #000000">
										<br />
										<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #0000ff">#define</span>
								<span style="COLOR: #000000"> Conn(x,y) x##y</span>
								<span style="COLOR: #000000">
										<br />
										<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
										<br />
										<img alt="" src="http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #0000ff">int</span>
								<span style="COLOR: #000000"> a</span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000">Conn(A,B);</span>
						</div>
				</div>
				<p>结果是a=5;可见一个宏的参数是另一个宏，先替换外面的宏，后替换参数。即Conn(A,B)=&gt;AB,后AB=&gt;5<br /></p>
				<p>
						<font color="#ff0000"> 5.解决重复定义的问题</font>
						<br />由于头文件包含可以嵌套，那么C文件就有可能包含多次同一个头文件，就可能出现重复定义的问题的。<br />通过条件编译开关来避免重复包含（重复定义）<br />例如<br />#ifndef __headerfileXXX__<br />＃define __headerfileXXX__<br />…<br />文件内容<br />…<br />#endif<br /></p>
				<p class="right articalinfo">发表于 @ <a title="permalink" href="http://blog.csdn.net/czsd82/archive/2007/06/07/1642101.aspx">2007年06月07日 12:29:00</a>|<a title="评论" href="http://blog.csdn.net/czsd82/archive/2007/06/07/1642101.aspx#FeedBack">评论(<span id="FeedbackCount_1642101">3</span><script type="text/javascript"><![CDATA[ddFeedbackCountStack("1642101")]]&gt;</script>
 )</a>|<a title="编辑" href="http://writeblog.csdn.net/PostEdit.aspx?entryId=1642101">编辑</a></p>
				<span id="Post.ascx_ViewPost_PreviousAndNextEntriesDown">
						<h3>
								<a href="http://blog.csdn.net/czsd82/archive/2007/06/25/1665727.aspx">新一篇: Java doc 书写标准 &amp; Java 程序 代码标准</a> | <a href="http://blog.csdn.net/czsd82/archive/2007/05/25/1626187.aspx">旧一篇: Windows快捷键大全 </a></h3>
				</span>
		</div>
		<div class="commentslist">
				<span id="Anthem_Post.ascx_Comments_ltlComments__">
						<span id="Post.ascx_Comments_ltlComments">
								<div id="commentslist">
										<h3>评论</h3>
										<dl class="question">
												<dt>
														<a title="permalink: 回复:#define用法归类" href="http://blog.csdn.net/czsd82/archive/2007/06/07/1642101.aspx#792315">#</a>
														<a name="792315">
														</a>zxy861114 发表于2008-04-15 19:45:32  IP: 222.246.211.* 
</dt>
												<dd>受教，谢谢，呵呵！<br />不过想问一个问题<br />#if defined(WIN32)<br />#define VTK_TK_EXPORT __declspec( dllexport )<br />#else<br />#define VTK_TK_EXPORT<br />#endif<br />看见else后面的 #define VTK_TK_EXPORT 没，<br />为什么它后面只一个字符串，而没有跟数字或是宏啊，<br />这什么意思？</dd>
										</dl>
										<dl class="question">
												<dt>
														<a title="permalink: 回复:#define用法归类" href="http://blog.csdn.net/czsd82/archive/2007/06/07/1642101.aspx#810233">#</a>
														<a name="810233">
														</a>weiren2006 发表于2008-05-19 00:10:26  IP: 61.144.144.* 
</dt>
												<dd>谢谢啊，终于明白一些define的用法了</dd>
										</dl>
										<dl class="question">
												<dt>
														<a title="permalink: 回复:#define用法归类" href="http://blog.csdn.net/czsd82/archive/2007/06/07/1642101.aspx#814206">#</a>
														<a name="814206">
														</a>catmonkeyxu 发表于2008-05-26 11:15:03  IP: 10.0.4.* 
</dt>
												<dd>用VC6.0试了下：<br />#define Conn(x,y) x##y<br />#define ToChar(x) #@x<br />#define ToString(x) #x<br /><br />int a = Conn(12,34);<br />char b = ToChar(a);<br />char c[]= ToString(a);<br /><br />最终c是"a"，不是"1234"啊<br />望楼主解疑！</dd>
										</dl>
								</div>
						</span>
				</span>
		</div>
<img src ="http://www.cnitblog.com/guopingleee/aggbug/54057.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/guopingleee/" target="_blank">向左向右走</a> 2009-01-30 12:51 <a href="http://www.cnitblog.com/guopingleee/archive/2009/01/30/54057.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>