﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-Stay Hungry Stay Foolish</title><link>http://www.cppblog.com/linzheng/</link><description>Just have a little faith.</description><language>zh-cn</language><lastBuildDate>Mon, 06 Apr 2026 22:48:25 GMT</lastBuildDate><pubDate>Mon, 06 Apr 2026 22:48:25 GMT</pubDate><ttl>60</ttl><item><title>C++基础（11）C++宏定义</title><link>http://www.cppblog.com/linzheng/archive/2012/10/18/193447.html</link><dc:creator>linzheng</dc:creator><author>linzheng</author><pubDate>Wed, 17 Oct 2012 16:27:00 GMT</pubDate><guid>http://www.cppblog.com/linzheng/archive/2012/10/18/193447.html</guid><wfw:comment>http://www.cppblog.com/linzheng/comments/193447.html</wfw:comment><comments>http://www.cppblog.com/linzheng/archive/2012/10/18/193447.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/linzheng/comments/commentRss/193447.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/linzheng/services/trackbacks/193447.html</trackback:ping><description><![CDATA[<div class="card-summary-content">
<p>C++ <a href="http://baike.baidu.com/view/2076445.htm" target="_blank">宏定义</a>将一个<a href="http://baike.baidu.com/view/390932.htm" target="_blank">标识符</a>定义为一个字符串，源程序中的该标识符均以指定的字符串来代替。前面已经说过，<a href="http://baike.baidu.com/view/1334643.htm" target="_blank">预处理命令</a>不同于一般C++语句。因此预处理命令后通常不加分号。这并不是说所有的预处理命令后都不能有分号出现。由于宏定义只是用宏名对一个字符串进行简单的替换，因此如果在宏定义命令后加了分号，将会连同分号一起进行置换。</p></div>
<dl id="catalog-holder-2-0" class="holder2"></dl>
<div class="clear"></div>
<div id="lemmaContent-0" class="lemma-main-content">
<h2 class="headline-1 first bk-sidecatalog-title"><span class="headline-content">三种预处理功能</span></h2>　　C++提供的编译预处理功能主要有以下三种： 
<div class="spctrl"></div>　　（一）<a href="http://baike.baidu.com/view/2076445.htm" target="_blank">宏定义</a> 
<div class="spctrl"></div>　　（二） 文件包含 
<div class="spctrl"></div>　　（三） <a href="http://baike.baidu.com/view/1995627.htm" target="_blank">条件编译</a> 
<div class="spctrl"></div>　　在C++中，我们一般用const定义<a href="http://baike.baidu.com/view/8563732.htm" target="_blank">符号常量</a>。很显然，用const定义<a href="http://baike.baidu.com/view/346799.htm" target="_blank">常量</a>比用define定义常量更好。 
<div class="bpctrl"></div>
<h2 class="headline-1 bk-sidecatalog-title"><span class="headline-content">使用宏定义注意点</span></h2>　　在使用<a href="http://baike.baidu.com/view/2076445.htm" target="_blank">宏定义</a>时应注意的是： 
<div class="spctrl"></div>　　（a） 在书写#define 命令时，注意&lt;宏名&gt;和&lt;字符串&gt;之间用空格分开，而不是用等号连接。 
<div class="spctrl"></div>　　（b） 使用#define定义的<a href="http://baike.baidu.com/view/390932.htm" target="_blank">标识符</a>不是<a href="http://baike.baidu.com/view/296689.htm" target="_blank">变量</a>，它只用作宏替换，因此不占有内存。 
<div class="spctrl"></div>　　（c） 习惯上用大写字母表示&lt;宏名&gt;，这只是一种习惯的约定，其目的是为了与变量名区分，因为变量名 
<div class="spctrl"></div>　　通常用小写字母。 
<div class="spctrl"></div>　　如果某一个标识符被定义为宏名后，在取消该宏定义之前，不允许重新对它进行宏定义。取消宏定义使用如下命令： 
<div class="spctrl"></div>　　#undef&lt;标识符&gt; 
<div class="spctrl"></div>　　其中，undef是关键字。该命令的功能是取消对&lt;标识符&gt;已有的宏定义。被取消了宏定义的标识符，可以对它重新进行定义。 
<div class="spctrl"></div>　　宏定义可以嵌套，已被定义的标识符可以用来定义新的标识符。例如： 
<div class="spctrl"></div>　　#define PI 3.14159265 
<div class="spctrl"></div>　　#define R 10 
<div class="spctrl"></div>　　#define AREA (PI*R*R) 
<div class="bpctrl"></div>
<h2 class="headline-1 bk-sidecatalog-title"><span class="headline-content">带参数的宏定义形式</span></h2>　　带参数的<a href="http://baike.baidu.com/view/2076445.htm" target="_blank">宏定义</a>的一般形式如下： 
<div class="spctrl"></div>　　#define &lt;宏名&gt;（&lt;参数表&gt;） &lt;宏体&gt; 
<div class="spctrl"></div>　　其中， &lt;宏名&gt;是一个标识符，&lt;参数表&gt;中的参数可以是一个，也可以是多个，视具体情况而定，当有多个参数的时候，每个参数之间用逗号分隔。&lt;宏体&gt;是被替换用的字符串，宏体中的字符串是由参数表中的各个参数组成的<a href="http://baike.baidu.com/view/420676.htm" target="_blank">表达式</a>。例如： 
<div class="spctrl"></div>　　#define SUB(a,b) a-b 
<div class="spctrl"></div>　　如果在程序中出现如下语句： 
<div class="spctrl"></div>　　result=SUB(2, 3) 
<div class="spctrl"></div>　　则被替换为： 
<div class="spctrl"></div>　　result=2-3； 
<div class="spctrl"></div>　　如果程序中出现如下语句： 
<div class="spctrl"></div>　　result= SUB（x+1, y+2）; 
<div class="spctrl"></div>　　则被替换为： 
<div class="spctrl"></div>　　result=x+1-y+2; 
<div class="spctrl"></div>　　在这样的宏替换过程中，其实只是将参数表中的参数代入到宏体的表达式中去，上述例子中，即是将表达式中的a和b分别用2和3代入。 
<div class="spctrl"></div>　　我们可以发现：带参的宏定义与函数类似。如果我们把宏定义时出现的参数视为<a href="http://baike.baidu.com/view/1158689.htm" target="_blank">形参</a>，而在程序中引用宏定义时出现的参数视为<a href="http://baike.baidu.com/view/816501.htm" target="_blank">实参</a>。那么上例中的a和b就是形参，而2和3以及x+1和y+2都为实参。在宏替换时，就是用实参来替换&lt;宏体&gt;中的形参。 
<div class="bpctrl"></div>
<h2 class="headline-1 bk-sidecatalog-title"><span class="headline-content">使用带参数宏定义注意点</span></h2>　　在使用带参数的<a href="http://baike.baidu.com/view/2076445.htm" target="_blank">宏定义</a>时需要注意的是： 
<div class="spctrl"></div>　　（1）带参数的宏定义的&lt;宏体&gt;应写在一行上，如果需要写在多行上时，在每行结束时，使用续行符 "\"结 
<div class="spctrl"></div>　　束，并在该符号后按下<a href="http://baike.baidu.com/view/29849.htm" target="_blank">回车键</a>，最后一行除外。 
<div class="spctrl"></div>　　（2）在书写带参数的宏定义时，&lt;宏名&gt;与左括号之间不能出现空格，否则空格右边的部分都作为宏体。 
<div class="spctrl"></div>　　例如： 
<div class="spctrl"></div>　　#define ADD (x,y) x+y 
<div class="spctrl"></div>　　将会把"（x,y）x+y"的一个整体作为被定义的字符串。 
<div class="spctrl"></div>　　（3）定义带参数的宏时，宏体中与参数名相同的字符串适当地加上圆括号是十分重要的，这样能够避免 
<div class="spctrl"></div>　　可能产生的错误。例如,对于宏定义： 
<div class="spctrl"></div>　　#define SQ(x) x*x 
<div class="spctrl"></div>　　当程序中出现下列语句： 
<div class="spctrl"></div>　　m=SQ(a+b); 
<div class="spctrl"></div>　　替换结果为： 
<div class="spctrl"></div>　　m=a+b*a+b; 
<div class="spctrl"></div>　　这可能不是我们期望的结果，如果需要下面的替换结果： 
<div class="spctrl"></div>　　m=(a+b)*(a+b); 
<div class="spctrl"></div>　　应将宏定义修改为： 
<div class="spctrl"></div>　　#define SQ(x) (x)*(x) 
<div class="spctrl"></div>　　对于带参的宏定义展开置换的方法是：在程序中如果有带<a href="http://baike.baidu.com/view/816501.htm" target="_blank">实参</a>的宏（如"SUB（2,3）"），则按"#define"命令行中指定的字符串从左到右进行置换。如果串中包含宏中的<a href="http://baike.baidu.com/view/1158689.htm" target="_blank">形参</a>（如a、b），则将程序语句中相应的实参（可以是<a href="http://baike.baidu.com/view/346799.htm" target="_blank">常量</a>、<a href="http://baike.baidu.com/view/296689.htm" target="_blank">变量</a>或者<a href="http://baike.baidu.com/view/420676.htm" target="_blank">表达式</a>）代替形参，如果宏定义中的<a href="http://baike.baidu.com/view/263416.htm" target="_blank">字符</a>串中的字符不是参数字符（如a-b中的-号），则保留。这样就形成了置换的字符串。 
<div class="spctrl"></div>　　(4) 定义带参数的宏后，使用时最好避免使用表达式传参。这样可以在复杂的宏定义中避免（3）中出现的问题</div><img src ="http://www.cppblog.com/linzheng/aggbug/193447.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/linzheng/" target="_blank">linzheng</a> 2012-10-18 00:27 <a href="http://www.cppblog.com/linzheng/archive/2012/10/18/193447.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++基础（10）typedef与define</title><link>http://www.cppblog.com/linzheng/archive/2012/07/14/183438.html</link><dc:creator>linzheng</dc:creator><author>linzheng</author><pubDate>Sat, 14 Jul 2012 11:26:00 GMT</pubDate><guid>http://www.cppblog.com/linzheng/archive/2012/07/14/183438.html</guid><wfw:comment>http://www.cppblog.com/linzheng/comments/183438.html</wfw:comment><comments>http://www.cppblog.com/linzheng/archive/2012/07/14/183438.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/linzheng/comments/commentRss/183438.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/linzheng/services/trackbacks/183438.html</trackback:ping><description><![CDATA[#define 是宏命令，在编译前，由预处理器做替代，如同文本编辑的替代命令，把程序中的所有遇到的词，全部替代。<br /><br />#define PINT int* <br />就是把所有的词 PINT 替换成 int * ，替换完毕再编译。 <br /><br />typedef int* pint; 是语句，由编译器在编译过程中编译处理。<br />int* x; 和<br />pint x; 的声明是等价的<br /><br />typedef int* pint;<br />long int* x; 声明是可以的，但<br />long pint x; 不可以。<br /><br />#define PINT int* <br />long int* x; 声明是可以的，<br />long PINT x; 也是可以的。<br />-----------------------------------------------------------<br />1) #define是预处理指令，在编译预处理时进行简单的替换，不作正确性检查，不关含义是否正确照样带入，只有在编译已被展开的源程序时才会发现可能的错误并报错。例如： <br />#define PI 3.1415926 <br />程序中的：area=PI*r*r 会替换为3.1415926*r*r <br />如果你把#define语句中的数字9 写成字母g 预处理也照样带入。 <br /><br />2）typedef是在编译时处理的。它在自己的作用域内给一个已经存在的类型一个别名，但是You cannot use the typedef specifier inside a function definition。 <br /><br />3）typedef int * int_ptr; <br />与 <br />#define int_ptr int * <br />作用都是用int_ptr代表 int * ,但是二者不同，正如前面所说 ，#define在预处理 时进行简单的替换，而typedef不是简单替换 ，而是采用如同定义变量的方法那样来声明一种类型。也就是说; <br /><br />//refer to (xzgyb(老达摩)) <br />#define int_ptr int * <br />int_ptr a, b; //相当于int * a, b; 只是简单的宏替换 <br /><br />typedef int* int_ptr; <br />int_ptr a, b; //a, b 都为指向int的指针,typedef为int* 引入了一个新的助记符 <br /><br /><br />这也说明了为什么下面观点成立 <br />//QunKangLi(维护成本与程序员的创造力的平方成正比) <br />typedef int * pint ; <br />#define PINT int * <br /><br />那么： <br />const pint p ;//p不可更改，但p指向的内容可更改 <br />const PINT p ;//p可更改，但是p指向的内容不可更改。 <br /><br />pint是一种指针类型 const pint p 就是把指针给锁住了 p不可更改 <br />而const PINT p 是const int * p 锁的是指针p所指的对象。 <br /><br />3）也许您已经注意到#define 不是语句 不要在行末加分号，否则 会连分号一块置换。<br /><br />另转一篇<br /><br /><strong><span style="font-size: 16px">一、typedef的用法</span></strong> 
<div class="sysBr500 text" align="left">
<p><span style="font-size: 16px">&nbsp;&nbsp;&nbsp; 在C/C++语言中，typedef常用来定义一个标识符及关键字的别名，它是语言编译过程的一部分，但它并不实际分配内存空间，实例像：</span></p>
<p><strong><span style="font-size: 16px">typedef int INT;<br />typedef int ARRAY[10];<br />typedef (int*) pINT;</span></strong></p>
<p><span style="font-size: 16px">&nbsp;&nbsp;&nbsp; typedef可以增强程序的可读性，以及标识符的灵活性，但它也有&#8220;非直观性&#8221;等缺点。</span></p>
<p><strong><span style="font-size: 16px">二、#define的用法</span></strong></p>
<p><span style="font-size: 16px">&nbsp;&nbsp;&nbsp; #define为一宏定义语句，通常用它来定义常量(包括无参量与带参量)，以及用来实现那些&#8220;表面似和善、背后一长串&#8221;的宏，它本身并不在编译过程中进行，而是在这之前(预处理过程)就已经完成了，但也因此难以发现潜在的错误及其它代码维护问题，它的实例像：</span></p>
<p><strong><span style="font-size: 16px">#define&nbsp;&nbsp; INT &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int#define TRUE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1#define&nbsp;&nbsp; Add(a,b)&nbsp;&nbsp;&nbsp;&nbsp; ((a)+(b));#define&nbsp;&nbsp;&nbsp; Loop_10&nbsp;&nbsp;&nbsp; for (int i=0; i&lt;10; i++)</span></strong></p>
<p><span style="font-size: 16px">&nbsp;&nbsp;&nbsp; 在Scott Meyer的Effective C++一书的条款1中有关于#define语句弊端的分析，以及好的替代方法，大家可参看。</span></p>
<p><strong><span style="font-size: 16px">三、#typedef与#define的区别</span></strong></p>
<p><span style="font-size: 16px">&nbsp;&nbsp;&nbsp; 从以上的概念便也能基本清楚，typedef只是为了增加可读性而为标识符另起的新名称(仅仅只是个别名)，而#define原本在C中是为了定义常量， 到了C++，const、enum、inline的出现使它也渐渐成为了起别名的工具。有时很容易搞不清楚与typedef两者到底该用哪个好，如 #define INT int这样的语句，用typedef一样可以完成，用哪个好呢？我主张用typedef，因为在早期的许多C编译器中这条语句是非法的，只是现今的编译器 又做了扩充。为了尽可能地兼容，一般都遵循#define定义&#8220;可读&#8221;的常量以及一些宏语句的任务，而typedef则常用来定义关键字、冗长的类型的别 名。</span></p>
<p><span style="font-size: 16px">&nbsp;&nbsp;&nbsp; 宏定义只是简单的字符串代换(原地扩展)，而typedef则不是原地扩展，它的新名字具有一定的封装性，以致于新命名的标识符具有更易定义变量的功能。请看上面第一大点代码的第三行：</span></p>
<p><span style="font-size: 16px"><strong>typedef&nbsp;&nbsp;&nbsp; (int*)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pINT;</strong>以及下面这行:<strong>#define&nbsp;&nbsp;&nbsp; pINT2&nbsp;&nbsp; int*</strong></span></p>
<p><span style="font-size: 16px">&nbsp;&nbsp;&nbsp; 效果相同？实则不同！实践中见差别：pINT a,b;的效果同int *a; int *b;表示定义了两个整型指针变量。而pINT2 a,b;的效果同int *a, b;表示定义了一个整型指针变量a和整型变量b。</span></p>
<p><span style="font-size: 16px">&nbsp;&nbsp;&nbsp; 注意：两者还有一个行尾;号的区别哦！</span></p></div><img src ="http://www.cppblog.com/linzheng/aggbug/183438.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/linzheng/" target="_blank">linzheng</a> 2012-07-14 19:26 <a href="http://www.cppblog.com/linzheng/archive/2012/07/14/183438.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++基础（9）指针的运算</title><link>http://www.cppblog.com/linzheng/archive/2012/07/14/183371.html</link><dc:creator>linzheng</dc:creator><author>linzheng</author><pubDate>Sat, 14 Jul 2012 06:45:00 GMT</pubDate><guid>http://www.cppblog.com/linzheng/archive/2012/07/14/183371.html</guid><wfw:comment>http://www.cppblog.com/linzheng/comments/183371.html</wfw:comment><comments>http://www.cppblog.com/linzheng/archive/2012/07/14/183371.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/linzheng/comments/commentRss/183371.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/linzheng/services/trackbacks/183371.html</trackback:ping><description><![CDATA[<strong>&nbsp;1.4.1赋值运算</strong> 
<p>&nbsp;&nbsp;&nbsp; 指针变量的赋值运算有以下几种形式：</p>
<p>&nbsp;&nbsp;&nbsp; 1.4.1.1指针变量初始化赋值如下：</p>
<p>&nbsp;&nbsp;&nbsp; int a；</p>
<p>&nbsp;&nbsp;&nbsp; int *ip=&amp;a；</p>
<p>&nbsp;&nbsp;&nbsp; 1.4.1.2把一个变量的地址赋予指向相同数据类型的指针变量。例如：<br /></p>
<table bordercolor="#cccccc" cellspacing="0" cellpadding="3" width="100%" bgcolor="#ffffff" border="2">
<tbody>
<tr>
<td>
<p>&nbsp;int a;</p>
<p>int *ip;</p>
<p>ip=&amp;a;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //把整型变量a的地址赋予整型指针变量ip</p>
<p>&nbsp;</p></td></tr></tbody></table>
<p>&nbsp;</p>&nbsp;&nbsp;&nbsp; 1.4.1.3把一个指针变量的值赋予指向相同类型变量的另一个指针变量。例如：<br />
<table bordercolor="#cccccc" cellspacing="0" cellpadding="3" width="100%" bgcolor="#ffffff" border="2">
<tbody>
<tr>
<td>
<p>&nbsp;int a;</p>
<p>int *pa=&amp;a;</p>
<p>int *pb;</p>
<p>pb=pa;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //把a的地址赋予指针变量pb</p></td></tr></tbody></table>
<p>&nbsp;&nbsp;&nbsp; 由于pa，pb均为指向整型变量的指针变量，因此可以相互赋值。</p>
<p>&nbsp;&nbsp;&nbsp; 1.4.1.4把数组的首地址赋予指向数组的指针变量。例如：<br /></p>
<table bordercolor="#cccccc" cellspacing="0" cellpadding="3" width="100%" bgcolor="#ffffff" border="2">
<tbody>
<tr>
<td>
<p>&nbsp;int a[5],*pa;</p>
<p>pa=a;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //数组名表示数组的首地址，故可赋予指向数组的指针变量pa</p>
<p>也可写为：</p>
<p>pa=&amp;a[0];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //数组第一个元素的地址也是整个数组的首地址也可赋予pa</p>
<p>当然也可采取初始化赋值的方法：</p>
<p>int a[5],*pa=a;</p></td></tr></tbody></table>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 以上是一些基本的数组赋值方法，后面我们会详细讨论指针在数组中的使用。</p>
<p>&nbsp;&nbsp;&nbsp; 1.4.1.5把字符串的首地址赋予指向字符类型的指针变量。例如：<br /></p>
<table bordercolor="#cccccc" cellspacing="0" cellpadding="3" width="100%" bgcolor="#ffffff" border="2">
<tbody>
<tr>
<td>
<p>&nbsp;char *pc;</p>
<p>pc="c language";</p>
<p>或用初始化赋值的方法写为：</p>
<p>char *pc=" c language ";</p></td></tr></tbody></table>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 这里应说明的是并不是把整个字符串装入指针变量， 而是把存放该字符串的字符数组的首地址装入指针变量。</p>
<p>&nbsp;&nbsp;&nbsp; 1.4.1.6把函数的入口地址赋予指向函数的指针变量。例如：</p>
<p>&nbsp;&nbsp;&nbsp; int （*pf）（）；</p>
<p>&nbsp;&nbsp;&nbsp; pf=f；&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //f为函数名</p>
<p>&nbsp;&nbsp;&nbsp;<strong> 1.4.2加减运算</strong></p>
<p>&nbsp;&nbsp;&nbsp; 对于指向数组的指针变量，可以加上或减去一个整数n.设ip是指向数组a的指针变量，则ip+n，ip-n，ip++，++ip，ip&#8212;&#8212;，&#8212;&#8212;ip 运算都是合法的。指针变量加或减一个整数n的意义是把指针指向的当前位置（指向某数组元素）向前或向后移动n个位置。应该注意，数组指针变量向前或向后移动一个位置和地址加1或减1 在概念上是不同的。因为数组可以有不同的类型， 各种类型的数组元素所占的字节长度是不同的。如指针变量加1，即向后移动1 个位置表示指针变量指向下一个数据元素的首地址。而不是在原地址基础上加1.看如下例子：<br /></p>
<table bordercolor="#cccccc" cellspacing="0" cellpadding="3" width="100%" bgcolor="#ffffff" border="2">
<tbody>
<tr>
<td>
<p>&nbsp;char a[20];</p>
<p>int*ip=a;</p>
<p>...</p>
<p>ip++;</p></td></tr></tbody></table>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 在上例中，指针ip的类型是int*，它指向的类型是int，它被初始化为指向整形变量a.接下来的第3句中，指针ip被加了1，编译器是这样处理的：它把指针ip的值加上了sizeof（int），在32位程序中，是被加上了4.由于地址是用字节做单位的，故ip所指向的地址由原来的变量a的地址向高地址方向增加了4个字节。</p>
<p>&nbsp;&nbsp;&nbsp; 由于char类型的长度是一个字节，所以，原来ptr是指向数组a的第0号单元开始的四个字节，此时指向了数组a中从第4号单元开始的四个字节。再看如下例子：<br /></p>
<table bordercolor="#cccccc" cellspacing="0" cellpadding="3" width="100%" bgcolor="#ffffff" border="2">
<tbody>
<tr>
<td>
<p>&nbsp;char a[20];</p>
<p>int*ip=a;</p>
<p>　　...</p>
<p>ip+=5;<br /></p></td></tr></tbody></table>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp; 在这个例子中，ip被加上了5，编译器是这样处理的：将指针ip的值加上5乘sizeof（int），在32位程序中就是加上了5乘4=20.由于地址的单位是字节，故现在的ip所指向的地址比起加5后的ip所指向的地址来说，向高地址方向移动了20个字节。在这个例子中，没加5前的ip指向数组a的第0号单元开始的四个字节，加5后，ptr已经指向了数组a的合法范围之外了。虽然这种情况在应用上会出问题，但在语法上却是可以的。这也体现出了指针的灵活性。</p>
<p>&nbsp;&nbsp;&nbsp; 如果上例中，ip是被减去5，那么处理过程大同小异，只不过ip的值是被减去5乘sizeof（int），新的ip指向的地址将比原来的ip所指向的地址向低地址方向移动了20个字节。</p>
<p>&nbsp;&nbsp;&nbsp; 总结一下，一个指针ipold加上一个整数n后，结果是一个新的指针ipnew，ipnew的类型和ipold的类型相同，ipnew所指向的类型和ipold所指向的类型也相同。ipnew的值将比ipold的值增加了n乘sizeof（ipold所指向的类型）个字节。就是说，ipnew所指向的内存区将比ipold所指向的内存区向高地址方向移动了n乘sizeof（ipold所指向的类型）个字节。</p>
<p>&nbsp;&nbsp;&nbsp; 一个指针ipold减去一个整数n后，结果是一个新的指针ipnew，ipnew的类型和ipold的类型相同，ipnew所指向的类型和ipold所指向的类型也相同。ipnew的值将比ipold的值减少了n乘sizeof（ipold所指向的类型）个字节，就是说，ipnew所指向的内存区将比ipold所指向的内存区向低地址方向移动了n乘sizeof（ipold所指向的类型）个字节。</p>
<p>&nbsp;&nbsp;&nbsp;<strong> 1.4.3关系运算</strong></p>
<p>&nbsp;&nbsp;&nbsp; 指向同一个数组中的不同元素的两个指针可以进行各种关系运算。例如：</p>
<p>&nbsp;&nbsp;&nbsp; ip1==ip2表示ip1和ip2指向同一数组元素</p>
<p>&nbsp;&nbsp;&nbsp; ip1&gt;ip2表示ip1处于高地址位置</p>
<p>&nbsp;&nbsp;&nbsp; ip1&lt;ip2表示ip2处于低地址位置</p>
<p>&nbsp;&nbsp;&nbsp; 指针变量还可以与0比较。设ip为指针变量，则ip==0表明ip是空指针，它不指向任何变量；ip！=0表示ip不是空指针。空指针是由对指针变量赋予0值而得到的。例如：</p>
<p>&nbsp;&nbsp;&nbsp; #define NULL 0</p>
<p>&nbsp;&nbsp;&nbsp; int *ip=NULL；</p>
<p>&nbsp;&nbsp;&nbsp; 对指针变量赋0值和不赋值是不同的。指针变量未赋值时，可以是任意值，是不能使用的。否则将造成意外错误。而指针变量赋0值后，则可以使用，只是它不指向具体的变量而已。</p><br />&nbsp;<strong>1.4.4取地址运算符</strong> 
<p>&nbsp;&nbsp;&nbsp; &#8216;&amp;&#8217;和取内容运算符&#8216;*&#8217;</p>
<p>&nbsp;&nbsp;&nbsp; 取地址运算符&amp;是单目运算符，其结合性为自右至左，其功能是取变量的地址。</p>
<p>&nbsp;&nbsp;&nbsp; 取内容运算符*是单目运算符，其结合性为自右至左，用来表示指针变量所指的变量。在*运算符之后跟的变量必须是指针变量。需要注意的是指针运算符*和指针变量说明中的指针说明符* 不是一回事。在指针变量说明中，&#8216;*&#8217;是类型说明符，表示其后的变量是指针类型。而表达式中出现的&#8216;*&#8217;则是一个运算符用以表示指针变量所指的变量。如下例子：<br /></p>
<table bordercolor="#cccccc" cellspacing="0" cellpadding="3" width="100%" bgcolor="#ffffff" border="2">
<tbody>
<tr>
<td>
<p>&nbsp;int a=12;</p>
<p>int b;</p>
<p>int *p;</p>
<p>int **ptr;</p>
<p>p=&amp;a;&nbsp;&nbsp; //&amp;a的结果是一个指针，类型是int*，指向的类型是int，指向的地址是a的</p>
<p>//地址。</p>
<p>*p=24;&nbsp;&nbsp; //*p的结果，在这里它的类型是int，它所占用的地址是p所指向的地址。</p>
<p>ptr=&amp;p; //&amp;p的结果是个指针，该指针的类型是p的类型加个*，在这里是int **。该</p>
<p>//指针所指向的类型是p的类型，这里是int*。该指针所指向的地址就是指针</p>
<p>//p自己的地址。</p>
<p>*ptr=&amp;b;//*ptr是个指针，&amp;b的结果也是个指针，且这两个指针的类型和所指向的类型//是一样的，所以用&amp;b来给*ptr赋值就是毫无问题的了。</p>
<p>**ptr=34;//*ptr的结果是ptr所指向的东西，在这里是一个指针，对这个指针再做一次*</p>
<p>//运算，结果就是一个int类型的变量。</p></td></tr></tbody></table>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;<strong>&nbsp; 1.4.5关于括号组合</strong></p>
<p>&nbsp;&nbsp;&nbsp; 在解释组合说明符时， 标识符右边的方括号和圆括号优先于标识符左边的&#8220;*&#8221;号，而方括号和圆括号以相同的优先级从左到右结合。但可以用圆括号改变约定的结合顺序。</p>
<p>&nbsp;&nbsp;&nbsp; 阅读组合说明符的规则是&#8220;从里向外&#8221;。从标识符开始，先看它右边有无方括号或园括号，如有则先作出解释，再看左边有无*号。 如果在任何时候遇到了闭括号，则在继续之前必须用相同的规则处理括号内的内容。</p>
<p>&nbsp;&nbsp;&nbsp;<strong> 1.5指针表达式</strong></p>
<p>&nbsp;&nbsp;&nbsp; 一个表达式的最后结果如果是一个指针，那么这个表达式就叫指针表式。所以指针表达式也具有指针所具有的四个要素：指针的类型，指针所指向的类型，指针指向的内存区，指针自身占据的内存。</p><img src ="http://www.cppblog.com/linzheng/aggbug/183371.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/linzheng/" target="_blank">linzheng</a> 2012-07-14 14:45 <a href="http://www.cppblog.com/linzheng/archive/2012/07/14/183371.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++基础（8）指针与内存管理</title><link>http://www.cppblog.com/linzheng/archive/2012/07/14/183367.html</link><dc:creator>linzheng</dc:creator><author>linzheng</author><pubDate>Sat, 14 Jul 2012 06:39:00 GMT</pubDate><guid>http://www.cppblog.com/linzheng/archive/2012/07/14/183367.html</guid><wfw:comment>http://www.cppblog.com/linzheng/comments/183367.html</wfw:comment><comments>http://www.cppblog.com/linzheng/archive/2012/07/14/183367.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/linzheng/comments/commentRss/183367.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/linzheng/services/trackbacks/183367.html</trackback:ping><description><![CDATA[<span style="font-size: 12pt; font-family: 黑体">指针与内存管理</span> 
<p style="margin: 6pt 0cm"><strong>&nbsp;</strong></p>
<p style="margin: 6pt 0cm"><strong>&nbsp;&nbsp; </strong>&nbsp;<span style="font-family: 宋体">利用指针你可以将数据写入内存中的任意位置，但是，一旦你的程序中有一个野指针</span>("wild<span style="font-family: 宋体">&#8221;</span>pointer)<span style="font-family: 宋体">，即指向一个错误位置的指针，你的数据就危险了&#8212;存放在堆中的数据可能会被破坏，用来管理堆的数据结构也可能会被破坏，甚至操作系统的数据也可能会被修改，有时，上述三种破坏情况会同时发生。所以合理的正确的分配指针的地址是非常重要的。</span></p>
<p style="margin: 6pt 0cm"><strong>&nbsp;</strong></p>
<h2 style="margin: 6pt 0cm; line-height: normal"><span style="font-size: 10.5pt">1.3.1</span><span style="font-size: 10.5pt; font-family: 黑体">内存分配的方式</span></h2>
<p style="margin: 6pt 0cm; text-indent: 21.75pt"><span style="font-family: 宋体">内存分配方式有三种：</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体">（</span>1<span style="font-family: 宋体">）从静态存储区域分配。内存在程序编译的时候就已经分配好，这块内存在程序的整个运行期间都存在。例如全局变量，</span>static<span style="font-family: 宋体">变量。</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体">（</span>2<span style="font-family: 宋体">）在栈上创建。在执行函数时，函数内局部变量的存储单元都可以在栈上创建，函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中，效率很高，但是分配的内存容量有限。</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体">（</span>3<span style="font-family: 宋体">）</span> <span style="font-family: 宋体">从堆上分配，亦称动态内存分配。程序在运行的时候用</span>malloc<span style="font-family: 宋体">或</span>new<span style="font-family: 宋体">申请任意多少的内存，程序员自己负责在何时用</span>free<span style="font-family: 宋体">或</span>delete<span style="font-family: 宋体">释放内存。动态内存的生存期由我们决定，使用非常灵活，但问题也最多，以下我们重点讲解动态内存分配。</span></p>
<h2 style="margin: 6pt 0cm; line-height: normal"><span style="font-size: 10.5pt">1.3.2</span><span style="font-size: 10.5pt"> malloc/free </span><span style="font-size: 10.5pt; font-family: 黑体">的使用要点</span></h2>
<p style="margin: 6pt 0cm; text-indent: 15.75pt">&nbsp;malloc<span style="font-family: 宋体">与</span>free<span style="font-family: 宋体">是</span>C/C++<span style="font-family: 宋体">语言的标准库函数，它用于申请动态内存和释放内存。</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体">函数</span>malloc<span style="font-family: 宋体">的原型如下：</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="background: #d9d9d9">void * malloc(size_t size); </span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体">用</span>malloc<span style="font-family: 宋体">申请一块长度为</span>length<span style="font-family: 宋体">的整数类型的内存，程序如下：</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="background: #d9d9d9">int *ip = (int *) malloc(sizeof(int) * length); </span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体">我们应当把注意力集中在两个要素上：&#8220;类型转换&#8221;和&#8220;</span>sizeof<span style="font-family: 宋体">&#8221;。</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt">&nbsp;malloc<span style="font-family: 宋体">函数返回值的类型是</span>void *<span style="font-family: 宋体">，所以在调用</span>malloc<span style="font-family: 宋体">时要显式地进行类型转换，将</span>void * <span style="font-family: 宋体">转换成所需要的指针类型。</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt">malloc<span style="font-family: 宋体">函数本身并不识别要申请的内存是什么类型，它只关心内存的总字节数。例如</span>int<span style="font-family: 宋体">变量在</span>16<span style="font-family: 宋体">位系统下是</span>2<span style="font-family: 宋体">个字节，在</span>32<span style="font-family: 宋体">位下是</span>4<span style="font-family: 宋体">个字节；而</span>float<span style="font-family: 宋体">变量在</span>16<span style="font-family: 宋体">位系统下是</span>4<span style="font-family: 宋体">个字节，在</span>32<span style="font-family: 宋体">位下也是</span>4<span style="font-family: 宋体">个字节。这个你可以用</span>sizeof(<span style="font-family: 宋体">类型</span>)<span style="font-family: 宋体">去测试。</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体">在</span>malloc<span style="font-family: 宋体">的&#8220;</span>()<span style="font-family: 宋体">&#8221;中使用</span>sizeof<span style="font-family: 宋体">运算符是良好的风格，但要当心有时我们会昏了头，写出</span> ip = malloc(sizeof(ip))<span style="font-family: 宋体">这样的程序来。</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体">函数</span>free<span style="font-family: 宋体">的原型如下：</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="background: #d9d9d9">void free( void * memblock ); </span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体">为什么</span>free<span style="font-family: 宋体">函数不象</span>malloc<span style="font-family: 宋体">函数那样复杂呢？这是因为指针</span>p<span style="font-family: 宋体">的类型以及它所指的内存的容量事先都是知道的，语句</span>free(p)<span style="font-family: 宋体">能正确地释放内存。如果</span>p<span style="font-family: 宋体">是</span>NULL<span style="font-family: 宋体">指针，那么</span>free<span style="font-family: 宋体">对</span>p<span style="font-family: 宋体">无论操作多少次都不会出问题。如果</span>p<span style="font-family: 宋体">不是</span>NULL<span style="font-family: 宋体">指针，那么</span>free<span style="font-family: 宋体">对</span>p<span style="font-family: 宋体">连续操作两次就会导致程序运行错误。</span></p>
<h2 style="margin: 6pt 0cm; line-height: normal"><span style="font-size: 10.5pt">1.3.3</span><span style="font-size: 10.5pt"> new/delete </span><span style="font-size: 10.5pt; font-family: 黑体">的使用要点</span></h2>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体">对于非内部数据类型的对象而言，光用</span>maloc/free<span style="font-family: 宋体">无法满足动态对象的要求。对象在创建的同时要自动执行构造函数，对象在消亡之前要自动执行析构函数。由于</span>malloc/free<span style="font-family: 宋体">是库函数而不是运算符，不在编译器控制权限之内，不能够把执行构造函数和析构函数的任务强加于</span>malloc/free<span style="font-family: 宋体">。</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体">因此</span>C++<span style="font-family: 宋体">语言需要一个能完成动态内存分配和初始化工作的运算符</span>new<span style="font-family: 宋体">，以及一个能完成清理与释放内存工作的运算符</span>delete<span style="font-family: 宋体">。注意</span>new/delete<span style="font-family: 宋体">不是库函数</span>,<span style="font-family: 宋体">只是</span>C++<span style="font-family: 宋体">的运算符。我们来看如下例子就知道怎么回事了。</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="background: #d9d9d9">class Object</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="background: #d9d9d9">{</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">public :</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　　</span><span style="background: #d9d9d9">Object(void){std::cout &lt;&lt; &#8220;Initialization&#8221;&lt;&lt; std::endl; }</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　　</span><span style="background: #d9d9d9">~Object(void){std::cout &lt;&lt; &#8220;Destroy&#8221;&lt;&lt; std::endl; }</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　　</span><span style="background: #d9d9d9">void Initialize(void){std:: cout &lt;&lt; &#8220;Initialization&#8221;&lt;&lt; std::endl; }</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　　</span><span style="background: #d9d9d9">void Destroy(void){ std::cout &lt;&lt; &#8220;Destroy&#8221;&lt;&lt; std::endl; }</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="background: #d9d9d9">}</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="background: #d9d9d9">void UseMallocFree(void)</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="background: #d9d9d9">{</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">Object *ip = (Object *)malloc(sizeof(Object)); &nbsp;&nbsp;&nbsp;// </span><span style="font-family: 宋体;background: #d9d9d9">申请动态内存</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">ip-&gt;Initialize(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// </span><span style="font-family: 宋体;background: #d9d9d9">初始化</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">//</span><span style="font-family: 宋体;background: #d9d9d9">&#8230;</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">ip-&gt;Destroy();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;// </span><span style="font-family: 宋体;background: #d9d9d9">清除工作</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">free(ip);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // </span><span style="font-family: 宋体;background: #d9d9d9">释放内存</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="background: #d9d9d9">}</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="background: #d9d9d9">void UseNewDelete(void)</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="background: #d9d9d9">{</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">Object *ip = new Object; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// </span><span style="font-family: 宋体;background: #d9d9d9">申请动态内存并且初始化</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">//</span><span style="font-family: 宋体;background: #d9d9d9">&#8230;</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">Delete ip; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// </span><span style="font-family: 宋体;background: #d9d9d9">清除并且释放内存</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="background: #d9d9d9">}</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">用</span>malloc/free<span style="font-family: 宋体">和</span>new/delete<span style="font-family: 宋体">如何实现对象的动态内存管理</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体">类</span>Object<span style="font-family: 宋体">的函数</span>Initialize<span style="font-family: 宋体">模拟了构造函数的功能，函数</span>Destroy<span style="font-family: 宋体">模拟了析构函数的功能。函数</span>UseMallocFree<span style="font-family: 宋体">中，由于</span>malloc/free<span style="font-family: 宋体">不能执行构造函数与析构函数，必须调用成员函数</span>Initialize<span style="font-family: 宋体">和</span>Destroy<span style="font-family: 宋体">来完成初始化与清除工作。函数</span>UseNewDelete<span style="font-family: 宋体">则简单得多。</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体">所以我们不要企图用</span>malloc/free<span style="font-family: 宋体">来完成动态对象的内存管理，应该用</span>new/delete<span style="font-family: 宋体">。由于内部数据类型的&#8220;对象&#8221;没有构造与析构的过程，对它们而言</span>malloc/free<span style="font-family: 宋体">和</span>new/delete<span style="font-family: 宋体">是等价的。</span>new<span style="font-family: 宋体">内置了</span>sizeof<span style="font-family: 宋体">、类型转换和类型安全检查功能</span>, ,<span style="font-family: 宋体">对于非内部数据类型的对象而言，</span>new<span style="font-family: 宋体">在创建动态对象的同时完成了初始化工作。</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt">new/delete <span style="font-family: 宋体">常使用的方法如下：</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="background: #d9d9d9">typeof *ip = new typeof[length];</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">类</span><span style="background: #d9d9d9">/</span><span style="font-family: 宋体;background: #d9d9d9">结构</span><span style="background: #d9d9d9"> *ip = new </span><span style="font-family: 宋体;background: #d9d9d9">类结构；</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">一般释放如下：</span><span style="background: #d9d9d9">delete ip;</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">数组的释放如下：</span><span style="background: #d9d9d9">delete [] ip;</span></p>
<h2 style="margin: 6pt 0cm; line-height: normal"><span style="font-size: 10.5pt">1.3.4</span><span style="font-size: 10.5pt; font-family: 黑体">内存耗尽怎么办？</span></h2>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体">如果在申请动态内存时找不到足够大的内存块，</span>malloc<span style="font-family: 宋体">和</span>new<span style="font-family: 宋体">将返回</span>NULL<span style="font-family: 宋体">指针，宣告内存申请失败。通常有三种方式处理&#8220;内存耗尽&#8221;问题。</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体">（</span>1<span style="font-family: 宋体">）判断指针是否为</span>NULL<span style="font-family: 宋体">，如果是则马上用</span>return<span style="font-family: 宋体">语句终止本函数。例如：</span></p>
<p style="margin: 6pt 0cm; text-indent: 26.25pt"><span style="background: #d9d9d9">void Func(void)</span></p>
<p style="margin: 6pt 0cm; text-indent: 26.25pt"><span style="background: #d9d9d9">{</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">A *a = new A;</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">if(a == NULL)</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">{</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　　</span><span style="background: #d9d9d9">return;</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">}</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　&#8230;</span></p>
<p style="margin: 6pt 0cm; text-indent: 26.25pt"><span style="background: #d9d9d9">} </span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体">（</span>2<span style="font-family: 宋体">）判断指针是否为</span>NULL<span style="font-family: 宋体">，如果是则马上用</span>exit(1)<span style="font-family: 宋体">终止整个程序的运行。例如：</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="background: #d9d9d9">void Func(void)</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="background: #d9d9d9">{</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">A *a = new A;</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">if(a == NULL)</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">{</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　　</span><span style="background: #d9d9d9">std::cout &lt;&lt; </span><span style="font-family: 宋体;background: #d9d9d9">&#8220;</span><span style="background: #d9d9d9">Memory Exhausted</span><span style="font-family: 宋体;background: #d9d9d9">&#8221;</span><span style="background: #d9d9d9"> &lt;&lt; std::endl;</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　　</span><span style="background: #d9d9d9">exit(1);</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">}</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　&#8230;</span></p>
<p style="margin: 6pt 0cm; text-indent: 26.25pt"><span style="background: #d9d9d9">} </span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体">（</span>3<span style="font-family: 宋体">）为</span>new<span style="font-family: 宋体">和</span>malloc<span style="font-family: 宋体">设置异常处理函数。例如</span>Visual C++<span style="font-family: 宋体">可以用</span>_set_new_hander<span style="font-family: 宋体">函数为</span>new<span style="font-family: 宋体">设置用户自己定义的异常处理函数，也可以让</span>malloc<span style="font-family: 宋体">享用与</span>new<span style="font-family: 宋体">相同的异常处理函数。详细内容请参考</span>C++<span style="font-family: 宋体">使用手册。</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt">&nbsp;<span style="font-family: 宋体">有一个很重要的现象要告诉大家。对于</span>32<span style="font-family: 宋体">位以上的应用程序而言，无论怎样使用</span>malloc<span style="font-family: 宋体">与</span>new<span style="font-family: 宋体">，几乎不可能导致&#8220;内存耗尽&#8221;。因为</span>32<span style="font-family: 宋体">位操作系统支持&#8220;虚存&#8221;，内存用完了，自动用硬盘空间顶替。我不想误导读者，必须强调：不加错误处理将导致程序的质量很差，千万不可因小失大。</span></p>
<h2 style="margin: 6pt 0cm; line-height: normal"><span style="font-size: 10.5pt">1.3. 5</span><span style="font-size: 10.5pt; font-family: 黑体">杜绝&#8220;野指针&#8221;</span></h2>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体">&#8220;野指针&#8221;不是</span>NULL<span style="font-family: 宋体">指针，是指向&#8220;垃圾&#8221;内存的指针。人们一般不会错用</span>NULL<span style="font-family: 宋体">指针，因为用</span>if<span style="font-family: 宋体">语句很容易判断。但是&#8220;野指针&#8221;是很危险的，</span>if<span style="font-family: 宋体">语句对它不起作用。</span> <span style="font-family: 宋体">&#8220;野指针&#8221;的原因主要有如下几种：</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体">（</span>1<span style="font-family: 宋体">）指针变量没有被初始化。任何指针变量刚被创建时不会自动成为</span>NULL<span style="font-family: 宋体">指针，它的缺省值是随机的，它会乱指一气。所以，指针变量在创建的同时应当被初始化，要么将指针设置为</span>NULL<span style="font-family: 宋体">，要么让它指向合法的内存。例如</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="background: #d9d9d9">char *ip = NULL;</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="background: #d9d9d9">char *ip = new char; </span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体">（</span>2<span style="font-family: 宋体">）指针</span>ip<span style="font-family: 宋体">被</span>free<span style="font-family: 宋体">或者</span>delete<span style="font-family: 宋体">之后，没有置为</span>NULL<span style="font-family: 宋体">，让人误以为</span>ip<span style="font-family: 宋体">是个合法的指针。</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体">（</span>3<span style="font-family: 宋体">）指针操作超越了变量的作用范围。这种情况让人防不胜防，示例程序如下：</span></p>
<p style="margin: 6pt 0cm; text-indent: 26.25pt"><span style="background: #d9d9d9">class A </span></p>
<p style="margin: 6pt 0cm; text-indent: 26.25pt"><span style="background: #d9d9d9">{ </span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">public:</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　　</span><span style="background: #d9d9d9">void Func(void){ std::cout &lt;&lt; </span><span style="font-family: 宋体;background: #d9d9d9">&#8220;</span><span style="background: #d9d9d9">Func of class A</span><span style="font-family: 宋体;background: #d9d9d9">&#8221;</span><span style="background: #d9d9d9"> &lt;&lt; std::endl; }</span></p>
<p style="margin: 6pt 0cm; text-indent: 26.25pt"><span style="background: #d9d9d9">};</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="background: #d9d9d9">void Test(void)</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="background: #d9d9d9">{</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">A *p;</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">{</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　　</span><span style="background: #d9d9d9">A a;</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　　</span><span style="background: #d9d9d9">p = &amp;a; // </span><span style="font-family: 宋体;background: #d9d9d9">注意</span><span style="background: #d9d9d9"> a </span><span style="font-family: 宋体;background: #d9d9d9">的生命期</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">}</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">p-&gt;Func(); // p</span><span style="font-family: 宋体;background: #d9d9d9">是&#8220;野指针&#8221;</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="background: #d9d9d9">} </span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体">函数</span>Test<span style="font-family: 宋体">在执行语句</span>p-&gt;Func()<span style="font-family: 宋体">时，对象</span>a<span style="font-family: 宋体">已经消失，而</span>p<span style="font-family: 宋体">是指向</span>a<span style="font-family: 宋体">的，所以</span>p<span style="font-family: 宋体">就成了&#8220;野指针&#8221;。但奇怪的是有些编译器运行这个程序时居然没有出错，这可能与编译器有关。</span></p>
<h2 style="margin: 6pt 0cm; line-height: normal"><span style="font-size: 10.5pt">1.3.6</span><span style="font-size: 10.5pt; font-family: 黑体">指针参数是如何传递内存的？</span></h2>
<p style="margin: 6pt 0cm; text-indent: 15.75pt">&nbsp;<span style="font-family: 宋体">如果函数的参数是一个指针，不要指望用该指针去申请动态内存。见如下例子：</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="background: #d9d9d9">void GetMemory(char *ip, int num)</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="background: #d9d9d9">{</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">ip = (char *)malloc(sizeof(char) * num);</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="background: #d9d9d9">}</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="background: #d9d9d9">void Test(void)</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="background: #d9d9d9">{</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">char *str = NULL;</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">GetMemory(str, 100); // str </span><span style="font-family: 宋体;background: #d9d9d9">仍然为</span><span style="background: #d9d9d9"> NULL </span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">strcpy(str, "hello"); // </span><span style="font-family: 宋体;background: #d9d9d9">运行错误</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="background: #d9d9d9">} </span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体">　　　　　　试图用指针参数申请动态内存</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体">　毛病出在函数</span>GetMemory<span style="font-family: 宋体">中。编译器总是要为函数的每个参数制作临时副本，指针参数</span>ip<span style="font-family: 宋体">的副本是</span> _ip<span style="font-family: 宋体">，编译器使</span> _ip = ip<span style="font-family: 宋体">。如果函数体内的程序修改了</span>_ip<span style="font-family: 宋体">的内容，就导致参数</span>ip<span style="font-family: 宋体">的内容作相应的修改。这就是指针可以用作输出参数的原因。在本例中，</span>_ip<span style="font-family: 宋体">申请了新的内存，只是把</span>_ip<span style="font-family: 宋体">所指的内存地址改变了，但是</span>ip<span style="font-family: 宋体">丝毫未变。所以函数</span>GetMemory<span style="font-family: 宋体">并不能输出任何东西。事实上，每执行一次</span>GetMemory<span style="font-family: 宋体">就会泄露一块内存，因为没有用</span>free<span style="font-family: 宋体">释放内存。</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体">如果非得要用指针参数去申请内存，那么应该改用&#8220;指向指针的指针&#8221;，见如下示例：</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="background: #d9d9d9">void GetMemory(char **p, int num)</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="background: #d9d9d9">{</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">*ip = (char *)malloc(sizeof(char) * num);</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="background: #d9d9d9">}</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="background: #d9d9d9">void Test(void)</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="background: #d9d9d9">{</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">char *str = NULL;</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">GetMemory(&amp;str, 100); // </span><span style="font-family: 宋体;background: #d9d9d9">注意参数是</span><span style="background: #d9d9d9"> &amp;str</span><span style="font-family: 宋体;background: #d9d9d9">，而不是</span><span style="background: #d9d9d9">str</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">strcpy(str, "hello"); </span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">std::cout&lt;&lt; str &lt;&lt; std::endl;</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">free(str); </span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="background: #d9d9d9">} </span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体">　　　　　　用指向指针的指针申请动态内存</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体">　当然，我们也可以用函数返回值来传递动态内存。这种方法更加简单，见如下示例：</span></p>
<p style="margin: 6pt 0cm; text-indent: 26.25pt"><span style="background: #d9d9d9">char *GetMemory(int num)</span></p>
<p style="margin: 6pt 0cm; text-indent: 26.25pt"><span style="background: #d9d9d9">{</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">char *ip = (char *)malloc(sizeof(char) * num);</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">return ip;</span></p>
<p style="margin: 6pt 0cm; text-indent: 26.25pt"><span style="background: #d9d9d9">}</span></p>
<p style="margin: 6pt 0cm; text-indent: 26.25pt"><span style="background: #d9d9d9">void Test(void)</span></p>
<p style="margin: 6pt 0cm; text-indent: 26.25pt"><span style="background: #d9d9d9">{</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">char *str = NULL;</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">str = GetMemory(100); </span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">strcpy(str, "hello");</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">std::cout&lt;&lt; str &lt;&lt; std::endl;</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">free(str); </span></p>
<p style="margin: 6pt 0cm; text-indent: 26.25pt"><span style="background: #d9d9d9">} </span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体">　　　　　　　用函数返回值来传递动态内存</span></p>
<p style="margin: 6pt 0cm; text-indent: 21pt"><span style="font-family: 宋体">用函数返回值来传递动态内存这种方法虽然好用，但是常常有人把</span>return<span style="font-family: 宋体">语句用错了。这里强调不要用</span>return<span style="font-family: 宋体">语句返回指向&#8220;栈内存&#8221;的指针，因为该内存在函数结束时自动消亡，见如下示例：</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="background: #d9d9d9">char *GetString(void)</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="background: #d9d9d9">{</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">char p[] = "hello world";</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">return p; // </span><span style="font-family: 宋体;background: #d9d9d9">编译器将提出警告</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="background: #d9d9d9">}</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="background: #d9d9d9">void Test(void)</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="background: #d9d9d9">{</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">char *str = NULL;</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">str = GetString(); // str </span><span style="font-family: 宋体;background: #d9d9d9">的内容是垃圾</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体;background: #d9d9d9">　</span><span style="background: #d9d9d9">std::cout&lt;&lt; str &lt;&lt; std::endl;</span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="background: #d9d9d9">} </span></p>
<p style="margin: 6pt 0cm; text-indent: 15.75pt"><span style="font-family: 宋体">　　　　　</span>return<span style="font-family: 宋体">语句返回指向&#8220;栈内存&#8221;的指针</span></p><img src ="http://www.cppblog.com/linzheng/aggbug/183367.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/linzheng/" target="_blank">linzheng</a> 2012-07-14 14:39 <a href="http://www.cppblog.com/linzheng/archive/2012/07/14/183367.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++基础（7）指针经典应用</title><link>http://www.cppblog.com/linzheng/archive/2012/07/14/183366.html</link><dc:creator>linzheng</dc:creator><author>linzheng</author><pubDate>Sat, 14 Jul 2012 06:36:00 GMT</pubDate><guid>http://www.cppblog.com/linzheng/archive/2012/07/14/183366.html</guid><wfw:comment>http://www.cppblog.com/linzheng/comments/183366.html</wfw:comment><comments>http://www.cppblog.com/linzheng/archive/2012/07/14/183366.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/linzheng/comments/commentRss/183366.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/linzheng/services/trackbacks/183366.html</trackback:ping><description><![CDATA[<p><br />指针经典应用:</p>
<p>1.<br />#include &lt;stdio.h&gt;<br />int main(void)&nbsp; <br />{&nbsp; <br />&nbsp; char str[]="hello world";<br />&nbsp; for(int i=0;i &lt;sizeof(str);i++)<br />&nbsp; cout&lt;&lt;i[str]&lt;&lt;'\n'; <br />&nbsp; getchar(); <br />} </p>
<p>结果:hello world<br />&nbsp;<br />/*在表达式中数组被隐式转换为指针<br />str[i]&nbsp; 为 *(str + i)<br />i[str]&nbsp; 为 *(i + str)<br />0[str+i]为 *(0+str+i)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */</p>
<p>&nbsp;</p>
<p>2.<br />#include&lt;iostream&gt;<br />using namespace std;<br />int main()<br />{<br />&nbsp;char *str[]={"welcome","to","Fortemedia","Nanjing"};<br />&nbsp;char**p=str+1;<br />&nbsp;str[0]=(*p++)+2;<br />&nbsp;str[1]=*(p+1);<br />&nbsp;str[2]=p[1]+3;<br />&nbsp;str[3]=p[0]+(str[2]-str[1]);<br />&nbsp;cout&lt;&lt;str[0]&lt;&lt;endl;<br />&nbsp;cout&lt;&lt;str[1]&lt;&lt;endl;<br />&nbsp;cout&lt;&lt;str[2]&lt;&lt;endl;<br />&nbsp;cout&lt;&lt;str[3]&lt;&lt;endl;<br />&nbsp;system("pause");<br />}</p>
<p>结果:<br />&nbsp;&nbsp;&nbsp;&nbsp; Nanjing<br />&nbsp;&nbsp;&nbsp;&nbsp; jing<br />&nbsp;&nbsp;&nbsp;&nbsp; g</p>
<p>/* str的值就是数组的起始地址值，str的值被默认解析成char **变量的值。</p>
<p>char**p=str+1;str指向的类型是char *型的，所以p的值是（int）str+sizeof（char*），显然p指向了str的第二个元素即str[1]的地址。</p>
<p>(*p++)+2;，p的值变为（int）p+sizeof（char*），，显然此时p指向了str[2]的地址，再进行*运算，由于后置是++返回未变化的p的值，取到了str[1]的值，即指向字符串"to"的指针的值，由于*p类型是char*的所以](*p++)+2;最终str[0]指向了&#8220;to&#8221;结尾的'/0'所以输出str[0]时为空。</p>
<p>str[1]=*(p+1);，显然str[1]指向了字符串"Nanjing"的首地址。cout&lt;&lt;str[1]&lt;&lt;endl;输出字符串Nanjing</p>
<p>很显然cout&lt;&lt;str[2]&lt;&lt;endl;输出jing</p>
<p>p指向了str[2]的地址，由于line9中，把&amp;str[2]~&amp;str[2]+3里的数据修改成了字符创"jing"的首地址。所以最终cout&lt;&lt;str[3]&lt;&lt;endl; 输出g。*/</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>3.<br />#include&lt;iostream&gt;<br />using namespace std;<br />int main()<br />{<br />&nbsp;int i[2]={1073741824,-1073741824};<br />&nbsp;int *p1=&amp;i[0];<br />&nbsp;char *p2=(char*)&amp;i[0];<br />&nbsp;float *p3=(float*)&amp;i[0];<br />&nbsp;cout&lt;&lt;*p1&lt;&lt;'\n'&lt;&lt;*p2&lt;&lt;'\n'&lt;&lt;*p3&lt;&lt;endl;<br />&nbsp;p1++;<br />&nbsp;p2++;<br />&nbsp;p3++;<br />&nbsp;cout&lt;&lt;*p1&lt;&lt;'\n'&lt;&lt;*p2&lt;&lt;'\n'&lt;&lt;*p3&lt;&lt;endl;<br />&nbsp;system("pause");<br />}</p>
<p><br />/* <br />上述代码中指针变量p1,p2,p3指向相同的地址值，都是i[0]所标识的内存的地址值，但由于指针的类型不同，导致用*运算符进行提领时，*p1,*p2,*p3的值不一样。当p1用*提领p1所指向的内存里的数据时，由于p1是int*型的，所以会从地址值为&amp;i[0]开始，往下涵盖四个字节（sizeof（int））的内存，然后把里面的数据安照int变量的存储方式解析成一个int型数值。1073741824在内存&amp;i[0]~&amp;i[0]+3中存储是0x00，0x00，0x00，0x40，（小段机 补码存储），所以*p1的值是1073741824。而p2是char*型的，所以仅从地址值为&amp;i[0]（sizeof（char））的内存把里面的数据按照char变量的存储方式解析成一个char型数值，由于地址值为&amp;[i]的内存里是0x00，所以*p2为0.同样由于p3是float*型的，所以会从地址值为&amp;i[0]开始，往下涵盖四个字节（sizeof（float））的内存，然后把里面的数据安照float变量的存储方式解析成一个float型数值。由于float型变量的存储方式不同于整型，c/c++浮点数存储遵循ieee标准，按照标准*p3的值为2.0（具体请参见本博客里一篇关于float内存布局的博文，不再赘述）。另外从上述代码我们可以看到，指针变量的类型还影响着指针变量算术运算时的跨度，即指针变量+1时，指针变量的值会增加sizeof（指针所指向变量的类型）。<br />*/</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>4.<br />#include &lt;iostream&gt;<br />using namespace std;<br />void arrayTest(char str[])<br />{<br />&nbsp;cout &lt;&lt; sizeof(str) &lt;&lt; endl;<br />}<br />int main(int argc, char* argv[])<br />{<br />&nbsp;char str1[10] = "I Love U";<br />&nbsp;arrayTest(str1); <br />&nbsp;system("pause");<br />} </p>
<p>结果:4</p>
<p>/*<br />(1)数组名作为函数形参时，在函数体内，其失去了本身的内涵，仅仅只是一个指针；</p>
<p>　　(2)很遗憾，在失去其内涵的同时，它还失去了其常量特性，可以作自增、自减等操作，可以被修改。</p>
<p>　　所以，数据名作为函数形参时，其全面沦落为一个普通指针！它的贵族身份被剥夺，成了一个地地道道的只拥有4个字节的平民。</p>
<p>*/</p>
<p><br />1.通过指针改变值：<br />#include &lt;iostream.h&gt;<br />void main()<br />{<br />int nNumber;<br />int *pPointer;<br />nNumber=15;<br />pPointer=&amp;nNumber;<br />cout&lt;&lt;"nNumber is equal to :"&lt;&lt;nNumber&lt;&lt;endl;<br />*pPointer=25;<br />cout&lt;&lt;"nNumber is equal to:"&lt;&lt;nNumber&lt;&lt;endl;<br />}</p>
<p>&nbsp;</p>
<p>2.传递指针到函数<br />#include &lt;iostream.h&gt;<br />void AddFive(int* Number)<br />{<br />*Number += 5;<br />}<br />void main()<br />{<br />int nMyNumber = 18;<br />cout&lt;&lt;"My original number is "&lt;&lt;nMyNumber&lt;&lt;endl;<br />AddFive(&amp;nMyNumber);<br />cout&lt;&lt;"My new number is "&lt;&lt;nMyNumber&lt;&lt;endl;<br />}</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><br />3.指向类的指针<br />class MyClass<br />{<br />public:<br />int m_Number;<br />char m_Character;<br />};<br />void main()<br />{<br />MyClass *pPointer;<br />pPointer = new MyClass;<br />pPointer-&gt;m_Number = 10;<br />pPointer-&gt;m_Character = 's';<br />delete pPointer;<br />}</p>
<p>&nbsp;</p>
<p>4.指向数组的指针<br />int *pArray;<br />pArray = new int[6];<br />或者：<br />int *pArray;<br />int MyArray[6];<br />pArray = &amp;MyArray[0];<br />//最后一行等价于：pArray = MyArray;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>5.利用指针变量访问数组元素<br />#include &lt;iostream.h&gt;<br />void main()<br />{<br />int size;<br />double array[] = {5.5,4.3,5.2,6.2,7.5};<br />double *p_array;<br />p_array=array;<br />size = sizeof(array)/sizeof(*array);<br />for(int i=0;i&lt;size;i++)<br />{<br />cout&lt;&lt;*(p_array+i)&lt;&lt;endl;<br />cout&lt;&lt;*(array+i)&lt;&lt;endl;<br />cout&lt;&lt;array[i]&lt;&lt;endl;<br />}<br />}</p>
<p>&nbsp;</p>
<p>6.二维数组表示<br />a[i][j]<br />*(a[i]+j)<br />*(*(a+i)+j)<br />(*(a+i))[j]<br />*(&amp;a[0][0]+2*i+j)</p>
<p>int a[3][2]={3，4，5}；<br />int *pi;<br />pi=&amp;a[0][0];//pi=a[0]<br />//pi=a;错误</p>
<p><br />int a[3][4],(*p)[4];<br />p=a;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>7.数组的结束标识符识别数组的长度<br />#include &lt;iostream.h&gt;<br />void sum(int *);<br />void main()<br />{<br />int a[]={10,20,30,40,50,NULL};<br />int i=0;<br />sum(a);<br />while(a[i]!=NULL)<br />{<br />cout&lt;&lt;a[i]&lt;&lt;"&nbsp;";<br />i++;<br />}<br />}<br />void sum(int *p)<br />{<br />int total=0;<br />int i=0;<br />while(p[i]!=NULL)<br />{<br />total+=p[i];<br />p[i]=0;<br />i++;<br />}<br />cout&lt;&lt;total&lt;&lt;endl;<br />}</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>8.const与指针<br />const int *pci;<br />pci=&amp;a;<br />*pci=55;//error!</p>
<p>int *const cpi=&amp;a;<br />*cpi=5;<br />cpi=&amp;b;//error!</p>
<p>const int *const cpc=&amp;b;<br />cpc=&amp;a;//error!<br />*cpc=44;//error!</p>
<p>&nbsp;</p>
<p>9.字符串指针<br />#include &lt;iostream.h&gt;<br />void main()<br />{<br />char *p="Language";<br />cout&lt;&lt;p&lt;&lt;endl;<br />for(int i=7;i&gt;=0;i--)<br />cout&lt;&lt;*(p+i);<br />cout&lt;&lt;endl;<br />}</p>
<p><br />char *p;<br />cin&gt;&gt;p;</p>
<p>char *p="fortran";<br />cout&gt;&gt;"p="&gt;&gt;p;</p>
<p>#include &lt;iostream.h&gt;<br />void main()<br />{<br />int len=0;<br />char a[10],*p=a;<br />cin&gt;&gt;p;<br />while(*(p+len)!='\0')<br />len++;<br />cout&lt;&lt;"p="&lt;&lt;p&lt;&lt;endl;<br />cout&lt;&lt;"len="&lt;&lt;len&lt;&lt;endl;<br />}</p>
<p>#include &lt;iostream.h&gt;<br />void main()<br />{<br />int len=0;<br />char a[20],*p=a;<br />cin.get(p,20);<br />while(*(p+len)!='\0')<br />len++;<br />cout&lt;&lt;p&lt;&lt;endl;<br />cout&lt;&lt;len&lt;&lt;endl;<br />}</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>10.引用<br />int a;<br />int &amp;r=a;</p>
<p>#include &lt;iostream.h&gt;<br />void swap(int *,int *);<br />void main()<br />{<br />int x=5,y=10;<br />cout&lt;&lt;"Main--(1)&lt;&lt;"x="&lt;&lt;x&lt;&lt;",y="&lt;&lt;y&lt;&lt;endl;<br />swap(&amp;x,&amp;y);<br />cout&lt;&lt;"Main--(2)"&lt;&lt;"x="&lt;&lt;x&lt;&lt;",y="&lt;&lt;y&lt;&lt;endl;<br />}<br />void swap(int *px,int *py)<br />{<br />int temp;<br />cout&lt;&lt;"Sub--(1)"&lt;&lt;"x="&lt;&lt;*px&lt;&lt;",y="&lt;&lt;*py&lt;&lt;endl;<br />temp=*px;<br />*px=*py;<br />*py=temp;<br />cout&lt;&lt;"Sub--"&lt;&lt;"x="&lt;&lt;*px&lt;&lt;",y="&lt;&lt;*py&lt;&lt;endl;<br />}</p>
<p>&nbsp;</p>
<p>#include &lt;iostream.h&gt;<br />int&amp; f(int,int*);<br />void main()<br />{<br />int a[]={1,3,5,7,9};<br />cout&lt;&lt;f(2,a)&lt;&lt;endl;<br />}<br />int&amp; f(int index,int *a)<br />{<br />int &amp;r=a[index];<br />return r;<br />}</p>
<p><br />11.数组指针<br />第i个元素地址的表示方法：<br />&amp;a[i],a+i,p+i,&amp;p[i];<br />第i个元素的表示方法：<br />a[i],*(a+i),*(p+i),p[i];</p>
<p>*p++等价于*(p++)</p>
<p>&nbsp;</p><img src ="http://www.cppblog.com/linzheng/aggbug/183366.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/linzheng/" target="_blank">linzheng</a> 2012-07-14 14:36 <a href="http://www.cppblog.com/linzheng/archive/2012/07/14/183366.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++基础（6）指针参数内存的传递 </title><link>http://www.cppblog.com/linzheng/archive/2012/07/14/183365.html</link><dc:creator>linzheng</dc:creator><author>linzheng</author><pubDate>Sat, 14 Jul 2012 06:33:00 GMT</pubDate><guid>http://www.cppblog.com/linzheng/archive/2012/07/14/183365.html</guid><wfw:comment>http://www.cppblog.com/linzheng/comments/183365.html</wfw:comment><comments>http://www.cppblog.com/linzheng/archive/2012/07/14/183365.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/linzheng/comments/commentRss/183365.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/linzheng/services/trackbacks/183365.html</trackback:ping><description><![CDATA[<span style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">在<span lang="EN-US">c++</span>中，函数的参数类型为结构体或类时，多数都是用指针和引用。如果函数的参数是一个指针，不要指望用该指针去申请动态内存。示例<span lang="EN-US">1</span>中，<span lang="EN-US">Test</span>函数的语句<span lang="EN-US">GetMemory(str, 200)</span>并没有使<span lang="EN-US">str</span>获得期望的内存，<span lang="EN-US">str</span>依旧是<span lang="EN-US">NULL</span>，为什么？请看下文。<span lang="EN-US"><br />&nbsp;<br />void GetMemory(char *p, int num)<br />{<br />&nbsp;p = (char *)malloc(sizeof(char) * num);<br />}<br />void Test(void)<br />{<br />&nbsp;char *str = NULL;<br />&nbsp;GetMemory(str, 100);&nbsp;// str </span>仍然为<span lang="EN-US"> NULL&nbsp;<br />&nbsp;strcpy(str, "hello");&nbsp;// </span>运行错误<span lang="EN-US"><br />}<br />&nbsp;&nbsp;&nbsp; </span>示例<span lang="EN-US">1 </span>试图用指针参数申请动态内存<span lang="EN-US"><br />&nbsp;<br />&nbsp;&nbsp;&nbsp; </span>问题出在函数<span lang="EN-US">GetMemory</span>中。编译器总是要为函数的每个参数制作临时副本，指针参数<span lang="EN-US">p</span>的副本是<span lang="EN-US"> _p</span>，编译器使<span lang="EN-US"> _p = p</span>。如果函数体内的程序修改了<span lang="EN-US">_p</span>的内容，就导致参数<span lang="EN-US">p</span>的内容作相应的修改。这就是指针可以用作输出参数的原因。在本例中，<span lang="EN-US">_p</span>申请了新的内存，只是把<span lang="EN-US">_p</span>所指的内存地址改变了，但是<span lang="EN-US">p</span>丝毫未变。所以函数<span lang="EN-US">GetMemory</span>并不能输出任何东西。事实上，每执行一次<span lang="EN-US">GetMemory</span>就会泄露一块内存，因为没有用<span lang="EN-US">free</span>释放内存。<span lang="EN-US"><br />&nbsp;&nbsp;&nbsp; </span>如果非得要用指针参数去申请内存，那么应该改用&#8220;指向指针的指针&#8221;，见示例<span lang="EN-US">2</span>。<span lang="EN-US"><br />&nbsp;<br /></span></span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">void GetMemory2(char **p, int num)<br />{<br />&nbsp;*p = (char *)malloc(sizeof(char) * num);<br />}<br />void Test2(void)<br />{<br />&nbsp;char *str = NULL;<br />&nbsp;GetMemory2(&amp;str, 100);&nbsp;// </span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">注意参数是</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA"> &amp;str</span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">，而不是</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">str<br />&nbsp;strcpy(str, "hello");&nbsp;<br />&nbsp;cout&lt;&lt; str &lt;&lt; endl;<br />&nbsp;free(str);&nbsp;<br />}<br />&nbsp;&nbsp;&nbsp; </span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">示例</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">2</span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">用指向指针的指针申请动态内存</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA"><br />&nbsp;<br />&nbsp;&nbsp;&nbsp; </span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">由于&#8220;指向指针的指针&#8221;这个概念不容易理解，我们可以用函数返回值来传递动态内存。这种方法更加简单，见示例</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">3</span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">。</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA"><br />&nbsp;<br />char *GetMemory3(int num)<br />{<br />&nbsp;char *p = (char *)malloc(sizeof(char) * num);<br />&nbsp;return p;<br />}<br />void Test3(void)<br />{<br />&nbsp;char *str = NULL;<br />&nbsp;str = GetMemory3(100);&nbsp;<br />&nbsp;strcpy(str, "hello");<br />&nbsp;cout&lt;&lt; str &lt;&lt; endl;<br />&nbsp;free(str);&nbsp;<br />}<br />&nbsp;&nbsp;&nbsp; </span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">示例</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">3 </span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">用函数返回值来传递动态内存</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA"><br />&nbsp;<br />&nbsp;&nbsp;&nbsp; </span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">用函数返回值来传递动态内存这种方法虽然好用，但是常常有人把</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">return</span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">语句用错了。</span><span style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">这里强调不要用<span lang="EN-US">return</span>语句返回指向&#8220;栈内存&#8221;的指针，因为该内存在函数结束时自动消亡，见示例<span lang="EN-US">4</span>。<span lang="EN-US"><br />&nbsp;<br /></span></span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">char *GetString(void)<br />{<br />&nbsp;char p[] = "hello world";<br />&nbsp;return p;&nbsp;// </span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">编译器将提出警告</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA"><br />}<br />void Test4(void)<br />{<br />char *str = NULL;<br />str = GetString();&nbsp;// str </span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">的内容是垃圾</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA"><br />cout&lt;&lt; str &lt;&lt; endl;<br />}<br />&nbsp;&nbsp;&nbsp; </span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">示例</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">4 return</span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">语句返回指向&#8220;栈内存&#8221;的指针</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA"><br />&nbsp;<br />&nbsp;&nbsp;&nbsp; </span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">用调试器逐步跟踪</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">Test4</span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">，发现执行</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">str = GetString</span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">语句后</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">str</span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">不再是</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">NULL</span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">指针，但是</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">str</span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">的内容不是&#8220;</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">hello world</span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">&#8221;而是垃圾。</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA"><br />&nbsp;&nbsp;&nbsp; </span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">如果把示例</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">4</span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">改写成示例</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">5</span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">，会怎么样？</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA"><br />&nbsp;<br />char *GetString2(void)<br />{<br />&nbsp;char *p = "hello world";<br />&nbsp;return p;<br />}<br />void Test5(void)<br />{<br />&nbsp;char *str = NULL;<br />&nbsp;str = GetString2();<br />&nbsp;cout&lt;&lt; str &lt;&lt; endl;<br />}<br />&nbsp;&nbsp;&nbsp; </span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">示例</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">5 return</span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">语句返回常量字符串</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA"><br />&nbsp;<br />&nbsp;&nbsp;&nbsp; </span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">函数</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">Test5</span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">运行虽然不会出错，但是函数</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">GetString2</span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">的设计概念却是错误的。因为</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">GetString2</span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">内的&#8220;</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">hello world</span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">&#8221;是常量字符串，位于静态存储区，它在程序生命期内恒定不变。无论什么时候调用</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">GetString2</span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">，它返回的始终是同一个&#8220;只读&#8221;的内存块。</span><span lang="EN-US" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA"><br />C++</span><span lang="JA" style="font-size: 10.5pt; font-family: 'SimSun','serif'; mso-bidi-font-family: Tahoma; mso-font-kerning: 0pt; mso-fareast-font-family: SimSun; mso-ansi-language: EN-US; mso-fareast-language: JA; mso-bidi-language: AR-SA">中，指针使用依旧很广泛，灵活性极大就注定了其危险程度会很高，所以在使用时一定要先明其理，再用之。</span><img src ="http://www.cppblog.com/linzheng/aggbug/183365.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/linzheng/" target="_blank">linzheng</a> 2012-07-14 14:33 <a href="http://www.cppblog.com/linzheng/archive/2012/07/14/183365.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++基础（5）指针入门</title><link>http://www.cppblog.com/linzheng/archive/2012/07/14/183362.html</link><dc:creator>linzheng</dc:creator><author>linzheng</author><pubDate>Sat, 14 Jul 2012 06:30:00 GMT</pubDate><guid>http://www.cppblog.com/linzheng/archive/2012/07/14/183362.html</guid><wfw:comment>http://www.cppblog.com/linzheng/comments/183362.html</wfw:comment><comments>http://www.cppblog.com/linzheng/archive/2012/07/14/183362.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/linzheng/comments/commentRss/183362.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/linzheng/services/trackbacks/183362.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp; 什么是指针？&nbsp;&nbsp;&nbsp; 其实指针就像是其它变量一样，所不同的是一般的变量包含的是实际的真实的数据，而指针是一个指示器，它告诉程序在内存的哪块区域可以找到数据。这是一个非常重要的概念，有很多程序和算法都是围绕指针而设计的，如链表。&nbsp;&nbsp;&nbsp; 开始学习&nbsp;&nbsp;&nbsp; 如何定义一个指针呢？就像你定义一个其...&nbsp;&nbsp;<a href='http://www.cppblog.com/linzheng/archive/2012/07/14/183362.html'>阅读全文</a><img src ="http://www.cppblog.com/linzheng/aggbug/183362.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/linzheng/" target="_blank">linzheng</a> 2012-07-14 14:30 <a href="http://www.cppblog.com/linzheng/archive/2012/07/14/183362.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++基础（4）自定义数组</title><link>http://www.cppblog.com/linzheng/archive/2012/07/08/182216.html</link><dc:creator>linzheng</dc:creator><author>linzheng</author><pubDate>Sun, 08 Jul 2012 08:56:00 GMT</pubDate><guid>http://www.cppblog.com/linzheng/archive/2012/07/08/182216.html</guid><wfw:comment>http://www.cppblog.com/linzheng/comments/182216.html</wfw:comment><comments>http://www.cppblog.com/linzheng/archive/2012/07/08/182216.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/linzheng/comments/commentRss/182216.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/linzheng/services/trackbacks/182216.html</trackback:ping><description><![CDATA[<p>下面使用VS2012来编写了自定义数组的程序：<br />程序目录如下：<br /><img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/linzheng/1.png" /><br />IntArray.h<br /></p>
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><span style="color: #000000">#include&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">stdafx.h</span><span style="color: #000000">"</span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />#include&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">iostream</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">namespace</span><span style="color: #000000">&nbsp;std;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;IntArray;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" />ostream</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">operator</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">(&nbsp;ostream&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">,&nbsp;IntArray</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;);</span><span style="color: #008000">//</span><span style="color: #008000">自定义输出操作符</span><span style="color: #008000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/None.gif" /></span><span style="color: #000000"><br /><img onclick="this.style.display='none'; Codehighlighter1_149_1099_Open_Text.style.display='none'; Codehighlighter1_149_1099_Closed_Image.style.display='inline'; Codehighlighter1_149_1099_Closed_Text.style.display='inline';" id="Codehighlighter1_149_1099_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_149_1099_Closed_Text.style.display='none'; Codehighlighter1_149_1099_Open_Image.style.display='inline'; Codehighlighter1_149_1099_Open_Text.style.display='inline';" id="Codehighlighter1_149_1099_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedBlock.gif"></span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;IntArray&nbsp;</span><span id="Codehighlighter1_149_1099_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_149_1099_Open_Text"><span style="color: #000000">{<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #0000ff">public</span><span style="color: #000000">:<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">构造函数</span><span style="color: #008000"><br /><img onclick="this.style.display='none'; Codehighlighter1_212_230_Open_Text.style.display='none'; Codehighlighter1_212_230_Closed_Image.style.display='inline'; Codehighlighter1_212_230_Closed_Text.style.display='inline';" id="Codehighlighter1_212_230_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_212_230_Closed_Text.style.display='none'; Codehighlighter1_212_230_Open_Image.style.display='inline'; Codehighlighter1_212_230_Open_Text.style.display='inline';" id="Codehighlighter1_212_230_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif"></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;IntArray(&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;sz&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;DefaultArraySize&nbsp;)&nbsp;</span><span id="Codehighlighter1_212_230_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_212_230_Open_Text"><span style="color: #000000">{&nbsp;init(&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">,&nbsp;sz&nbsp;);&nbsp;&nbsp;}</span></span><span style="color: #000000"><br /><img onclick="this.style.display='none'; Codehighlighter1_274_292_Open_Text.style.display='none'; Codehighlighter1_274_292_Closed_Image.style.display='inline'; Codehighlighter1_274_292_Closed_Text.style.display='inline';" id="Codehighlighter1_274_292_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_274_292_Closed_Text.style.display='none'; Codehighlighter1_274_292_Open_Image.style.display='inline'; Codehighlighter1_274_292_Open_Text.style.display='inline';" id="Codehighlighter1_274_292_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;IntArray(&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">ar,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;sz&nbsp;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_274_292_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_274_292_Open_Text"><span style="color: #000000">{&nbsp;init(&nbsp;ar,&nbsp;sz&nbsp;);&nbsp;}</span></span><span style="color: #000000"><br /><img onclick="this.style.display='none'; Codehighlighter1_329_357_Open_Text.style.display='none'; Codehighlighter1_329_357_Closed_Image.style.display='inline'; Codehighlighter1_329_357_Closed_Text.style.display='inline';" id="Codehighlighter1_329_357_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_329_357_Closed_Text.style.display='none'; Codehighlighter1_329_357_Open_Image.style.display='inline'; Codehighlighter1_329_357_Open_Text.style.display='inline';" id="Codehighlighter1_329_357_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;IntArray(&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;IntArray&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">iA&nbsp;)&nbsp;</span><span id="Codehighlighter1_329_357_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_329_357_Open_Text"><span style="color: #000000">{&nbsp;init(&nbsp;iA._ia,&nbsp;iA._size&nbsp;);&nbsp;}</span></span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">析构函数&nbsp;每个类对象在被程序，最后一次使用之后它的析构函数就会被自动调用</span><span style="color: #008000"><br /><img onclick="this.style.display='none'; Codehighlighter1_423_439_Open_Text.style.display='none'; Codehighlighter1_423_439_Closed_Image.style.display='inline'; Codehighlighter1_423_439_Closed_Text.style.display='inline';" id="Codehighlighter1_423_439_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_423_439_Closed_Text.style.display='none'; Codehighlighter1_423_439_Open_Image.style.display='inline'; Codehighlighter1_423_439_Open_Text.style.display='inline';" id="Codehighlighter1_423_439_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif"></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">virtual</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">~</span><span style="color: #000000">IntArray()&nbsp;</span><span id="Codehighlighter1_423_439_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_423_439_Open_Text"><span style="color: #000000">{&nbsp;delete[]&nbsp;_ia;&nbsp;}</span></span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">赋值操作符</span><span style="color: #008000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;IntArray</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">operator</span><span style="color: #000000">=</span><span style="color: #000000">(&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;IntArray</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;);<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">访问数组的大小</span><span style="color: #008000"><br /><img onclick="this.style.display='none'; Codehighlighter1_526_542_Open_Text.style.display='none'; Codehighlighter1_526_542_Closed_Image.style.display='inline'; Codehighlighter1_526_542_Closed_Text.style.display='inline';" id="Codehighlighter1_526_542_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_526_542_Closed_Text.style.display='none'; Codehighlighter1_526_542_Open_Image.style.display='inline'; Codehighlighter1_526_542_Open_Text.style.display='inline';" id="Codehighlighter1_526_542_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif"></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;size()&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span id="Codehighlighter1_526_542_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_526_542_Open_Text"><span style="color: #000000">{&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;_size;&nbsp;}</span></span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">相等与不相等操作符</span><span style="color: #008000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">operator</span><span style="color: #000000">==</span><span style="color: #000000">(&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;IntArray</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;)&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">bool</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">operator</span><span style="color: #000000">!=</span><span style="color: #000000">(&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;IntArray</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;)&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /><br /><img onclick="this.style.display='none'; Codehighlighter1_694_712_Open_Text.style.display='none'; Codehighlighter1_694_712_Closed_Image.style.display='inline'; Codehighlighter1_694_712_Closed_Text.style.display='inline';" id="Codehighlighter1_694_712_Open_Image" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif"><img onclick="this.style.display='none'; Codehighlighter1_694_712_Closed_Text.style.display='none'; Codehighlighter1_694_712_Open_Image.style.display='inline'; Codehighlighter1_694_712_Open_Text.style.display='inline';" id="Codehighlighter1_694_712_Closed_Image" style="display: none" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ContractedSubBlock.gif">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">virtual</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">operator</span><span style="color: #000000">[](&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;ix&nbsp;)&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span id="Codehighlighter1_694_712_Closed_Text" style="border-top: #808080 1px solid; border-right: #808080 1px solid; border-bottom: #808080 1px solid; border-left: #808080 1px solid; display: none; background-color: #ffffff"><img alt="" src="http://www.cppblog.com/Images/dot.gif" /></span><span id="Codehighlighter1_694_712_Open_Text"><span style="color: #000000">{&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;_ia[ix];&nbsp;}</span></span><span style="color: #000000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;ostream&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">print(&nbsp;ostream</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;os&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;cout&nbsp;)&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;grow();<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">virtual</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;sort(&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;);<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">virtual</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;find(&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;)&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">virtual</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;min()&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">virtual</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;max()&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">;<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #0000ff">protected</span><span style="color: #000000">:<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;init(&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">*</span><span style="color: #000000">,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;);<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;swap(&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;);<br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;内部数据</span><span style="color: #008000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;DefaultArraySize;</span><span style="color: #008000">//</span><span style="color: #008000">数组的默认大小</span><span style="color: #008000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_size;</span><span style="color: #008000">//</span><span style="color: #008000">数组的实际大小</span><span style="color: #008000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">_ia;</span><span style="color: #008000">//</span><span style="color: #008000">数组的指针</span><span style="color: #008000"><br /><img alt="" align="top" src="http://www.cppblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" /></span><span style="color: #000000">}</span></span><span style="color: #000000">;</span></div>
<p>IntArray.cpp<br /></p>
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000">#include&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">stdafx.h</span><span style="color: #000000">"</span><span style="color: #000000"><br />#include&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">assert.h</span><span style="color: #000000">&gt;</span><span style="color: #000000"><br />#include&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">IntArray.h</span><span style="color: #000000">"</span><span style="color: #000000"><br /><br /></span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">namespace</span><span style="color: #000000">&nbsp;std;<br /><br /></span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;IntArray::DefaultArraySize&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">12</span><span style="color: #000000">;<br /></span><span style="color: #008000">//</span><span style="color: #008000">初始化方法</span><span style="color: #008000"><br /></span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;IntArray::init(&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">array,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;sz&nbsp;)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(&nbsp;</span><span style="color: #000000">!</span><span style="color: #000000">&nbsp;array&nbsp;)&nbsp;{&nbsp;_size&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;_ia&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(&nbsp;sz&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">&nbsp;)&nbsp;sz&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">初始化数据</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;_size&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;sz;<br />&nbsp;&nbsp;&nbsp;&nbsp;_ia&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">[&nbsp;_size&nbsp;];<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">初始化内存</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;ix&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;ix&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;_size;&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">ix&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_ia[&nbsp;ix&nbsp;]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;array[&nbsp;ix&nbsp;];<br />}<br /><br />IntArray</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;IntArray::</span><span style="color: #0000ff">operator</span><span style="color: #000000">=</span><span style="color: #000000">(&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;IntArray&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">iA&nbsp;)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">如果是相同的指针，则返回本身的指针</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(&nbsp;</span><span style="color: #0000ff">this</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">iA&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #0000ff">this</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">否则，释放原来指针的内存，并重新初始化，返回当前的指针</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;delete[]&nbsp;_ia;<br />&nbsp;&nbsp;&nbsp;&nbsp;init(&nbsp;iA._ia,&nbsp;iA._size&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #0000ff">this</span><span style="color: #000000">;<br />}<br /><br />ostream</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">operator</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">(&nbsp;ostream&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">os,&nbsp;IntArray&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">ar&nbsp;)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;ar.print(&nbsp;os&nbsp;);<br />}<br /><br />ostream</span><span style="color: #000000">&amp;</span><span style="color: #000000">&nbsp;IntArray::print(&nbsp;ostream&nbsp;</span><span style="color: #000000">&amp;</span><span style="color: #000000">os&nbsp;)&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000"><br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;lineLength&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">12</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;os&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">(&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;_size&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;)&lt;&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;ix&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;ix&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;_size;&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">ix&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(&nbsp;ix&nbsp;</span><span style="color: #000000">%</span><span style="color: #000000">&nbsp;lineLength&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;ix&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;os&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">\n\t</span><span style="color: #000000">"</span><span style="color: #000000">;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;os&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;_ia[&nbsp;ix&nbsp;];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(&nbsp;ix&nbsp;</span><span style="color: #000000">%</span><span style="color: #000000">&nbsp;lineLength&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;lineLength</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">&amp;&amp;</span><span style="color: #000000">&nbsp;ix&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;_size</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;os&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;os&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;&gt;\n</span><span style="color: #000000">"</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;os;<br />}<br /></span><span style="color: #008000">//</span><span style="color: #008000">增加一半的数组元素</span><span style="color: #008000"><br /></span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;IntArray::grow()<br />{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">*</span><span style="color: #000000">oldia&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;_ia;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;oldSize&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;_size;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;_size&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;oldSize&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;oldSize</span><span style="color: #000000">/</span><span style="color: #000000">2</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;_ia&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">[_size];<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;ix;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(&nbsp;ix&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;ix&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;oldSize;&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">ix)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_ia[ix]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;oldia[ix];<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(&nbsp;;&nbsp;ix&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;_size;&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">ix&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_ia[ix]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">释放掉临时的指针</span><span style="color: #008000"><br /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;delete[]&nbsp;oldia;<br />}<br /></span><span style="color: #008000">//</span><span style="color: #008000">最小值</span><span style="color: #008000"><br /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;IntArray::min()&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000"><br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;assert(&nbsp;_ia&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;min_val&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;_ia[</span><span style="color: #000000">0</span><span style="color: #000000">];<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;ix&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">;&nbsp;ix&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;_size;&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">ix&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(&nbsp;_ia[ix]&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;min_val&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;min_val&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;_ia[ix];<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;min_val;<br />}<br /></span><span style="color: #008000">//</span><span style="color: #008000">最大值</span><span style="color: #008000"><br /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;IntArray::max()&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000"><br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;assert(&nbsp;_ia&nbsp;</span><span style="color: #000000">!=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;max_val&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;_ia[</span><span style="color: #000000">0</span><span style="color: #000000">];<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;ix&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">;&nbsp;ix&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;_size;&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">ix&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(&nbsp;max_val&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;_ia[ix]&nbsp;)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max_val&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;_ia[ix];<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;max_val;<br />}<br /></span><span style="color: #008000">//</span><span style="color: #008000">查找</span><span style="color: #008000"><br /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;IntArray::find(&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;val&nbsp;)&nbsp;</span><span style="color: #0000ff">const</span><span style="color: #000000"><br />{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;ix&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;&nbsp;ix&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;_size;&nbsp;</span><span style="color: #000000">++</span><span style="color: #000000">ix&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(&nbsp;val&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;_ia[ix]&nbsp;)&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;ix;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">;<br />}<br /></span><span style="color: #008000">//</span><span style="color: #008000">交换值</span><span style="color: #008000"><br /></span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;IntArray::swap(&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;i,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;j&nbsp;)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;tmp&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;_ia[i];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_ia[i]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;_ia[j];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_ia[j]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;tmp;<br />}<br /></span><span style="color: #008000">//</span><span style="color: #008000">排序</span><span style="color: #008000"><br /></span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;IntArray::sort(&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;low,&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;high&nbsp;)<br />{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(&nbsp;low&nbsp;</span><span style="color: #000000">&gt;=</span><span style="color: #000000">&nbsp;high&nbsp;)&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;lo&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;low;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;hi&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;high&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;elem&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;_ia[low];<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">for</span><span style="color: #000000">&nbsp;(&nbsp;;;&nbsp;)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">&nbsp;(&nbsp;_ia[</span><span style="color: #000000">++</span><span style="color: #000000">lo]&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;elem&nbsp;)&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">while</span><span style="color: #000000">&nbsp;(&nbsp;_ia[</span><span style="color: #000000">--</span><span style="color: #000000">hi]&nbsp;</span><span style="color: #000000">&gt;</span><span style="color: #000000">&nbsp;elem&nbsp;)&nbsp;;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">if</span><span style="color: #000000">&nbsp;(&nbsp;lo&nbsp;</span><span style="color: #000000">&lt;</span><span style="color: #000000">&nbsp;hi&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;swap(&nbsp;lo,hi&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">break</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;swap(&nbsp;low,&nbsp;hi&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;sort(&nbsp;low,&nbsp;hi</span><span style="color: #000000">-</span><span style="color: #000000">1</span><span style="color: #000000">&nbsp;);<br />&nbsp;&nbsp;&nbsp;&nbsp;sort(&nbsp;hi</span><span style="color: #000000">+</span><span style="color: #000000">1</span><span style="color: #000000">,&nbsp;high&nbsp;);<br />}<br /></span></div>
<p>&nbsp;</p>
<div style="font-size: 13px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; word-break: break-all; padding-bottom: 4px; padding-top: 4px; padding-left: 4px; border-left: #cccccc 1px solid; padding-right: 5px; width: 98%; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008000">//</span><span style="color: #008000">&nbsp;ArrayDemo.cpp&nbsp;:&nbsp;定义控制台应用程序的入口点。<br /></span><span style="color: #008000">//<br /></span><span style="color: #000000"><br />#include&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">stdafx.h</span><span style="color: #000000">"</span><span style="color: #000000"><br />#include&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">IntArray.h</span><span style="color: #000000">"</span><span style="color: #000000"><br /><br /><br /></span><span style="color: #0000ff">using</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">namespace</span><span style="color: #000000">&nbsp;std;<br /><br /><br /></span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;_tmain(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;argc,&nbsp;_TCHAR</span><span style="color: #000000">*</span><span style="color: #000000">&nbsp;argv[])<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;array[&nbsp;</span><span style="color: #000000">4</span><span style="color: #000000">&nbsp;]&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;{&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">2</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">3</span><span style="color: #000000">&nbsp;};<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IntArray&nbsp;ia1(&nbsp;array,&nbsp;</span><span style="color: #000000">4</span><span style="color: #000000">&nbsp;);<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;ia1.grow();<br />&nbsp;&nbsp;&nbsp;&nbsp;ia1.print();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;search_value;<br />&nbsp;&nbsp;&nbsp;&nbsp;cout&nbsp;</span><span style="color: #000000">&lt;&lt;</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">please&nbsp;enter&nbsp;search&nbsp;value:&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cin&nbsp;</span><span style="color: #000000">&gt;&gt;</span><span style="color: #000000">&nbsp;search_value;<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">0</span><span style="color: #000000">;<br />}<br /><br /></span></div>
<p><br /><br />运行的效果：<br /><img border="0" alt="" src="http://www.cppblog.com/images/cppblog_com/linzheng/QQ截图20120708163333.png" /><br /></p><img src ="http://www.cppblog.com/linzheng/aggbug/182216.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/linzheng/" target="_blank">linzheng</a> 2012-07-08 16:56 <a href="http://www.cppblog.com/linzheng/archive/2012/07/08/182216.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++基础（3）动态内存分配和指针 </title><link>http://www.cppblog.com/linzheng/archive/2012/07/08/182206.html</link><dc:creator>linzheng</dc:creator><author>linzheng</author><pubDate>Sun, 08 Jul 2012 06:51:00 GMT</pubDate><guid>http://www.cppblog.com/linzheng/archive/2012/07/08/182206.html</guid><wfw:comment>http://www.cppblog.com/linzheng/comments/182206.html</wfw:comment><comments>http://www.cppblog.com/linzheng/archive/2012/07/08/182206.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/linzheng/comments/commentRss/182206.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/linzheng/services/trackbacks/182206.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp; 在C++ 中，对象可以静态分配&#8212;&#8212; 即编译器在处理程序源代码时分配，也可以动态分配&#8212;&#8212; 即程序执行时调用运行时刻库函数来分配。这两种内存分配方法的主要区别是效率与灵活性之间的平衡准则不同。出于静态内存分配是在程序执行之前进行的，因而效率比较高，但是，它缺少灵活性，它要求在程序执行之前就知道所需内存的类型和数量，例如，利用静态分配的字符串数组，我们无法很容易地处理和存储任意的文本文件。一般来说，存储未知数目的元素需要动态内存分配的灵活性。</p>
<p>&nbsp;&nbsp;&nbsp; 到目前为止，所有的内存分配都是静态的 例如 int ival = 1024; 则是在程序编译的时候就已经分配好空间了。<br /><br /><span style="font-size: 18pt">怎样访问和存储内存地址呢？</span><br />&nbsp;&nbsp;&nbsp; C++ 支持用指针类型来存放对象的内存地址值，例如为了声明一个能存放ival 内存地址的指针类型，我们可以这样写：<br />//&nbsp; 一个指向int 类型的指针 <br />int *pint; <br />&nbsp;&nbsp;&nbsp; C++ 预定义了一个专门的取地址操作符&amp;，当我们把它应用在一个对象上时返回的是对象的地址值。因此为了将ival 内存地址值赋给pint 我们可以这样写：<br />int *pint; <br />pint = &amp;ival; // 把ival 的地址pint <br />&nbsp;&nbsp;&nbsp; 了访问pint 所指向的实际对象，我们必须先用解引用操作符* 来解除pint 的引用pint。例如下面我们通过pint 间接地给ival 加1&nbsp; <br />//&nbsp; 通过pint 间接地给ival 加1 <br />*pint = *pint + 1; <br />&nbsp;&nbsp;&nbsp;&nbsp; 它等价于下面直接对ival 操作的语句&nbsp;<br />&nbsp;//&nbsp; 直接给ival 加1 <br />ival = ival + 1;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; 在本例中使用指针间接地操作ival，没有什么实际的好处这样做比直接操作ival 的效率要低，而且又容易出错。我们只是用它来简单地介绍一下指针在C++ 中指针的主要用处是管理和操纵动态分配的内存。<br />&nbsp;&nbsp;&nbsp; &nbsp;<span style="font-size: 18pt">静态与动态内存分配的两个主要区别是 </span><br />&nbsp;&nbsp;&nbsp; 1. 静态对象是有名字的变量，我们直接对其进行操作，而动态对象是没有名字的变量，我们通过指针间接地对它进行操作。&nbsp;<br />&nbsp;&nbsp;&nbsp; 2. 静态对象的分配与释放由编译器自动处理，程序员需要理解这一点但不需要做任何事情。相反动态对象的分配与释放必须由程序员显式地管理，相对来说比较容易出错，它通过new 和delete 两个表达式来完成。<br />对象的动态分配的两种方式：<br />第一种：int *pint = new int( 1024 ); <br />&nbsp;&nbsp;&nbsp; 分配了一个没有名字的int 类型的对象对象初始值为1024，然后表达式返回对象在内存中的地址，接着这个地址被用来初始化指针对象pint。对于动态分配的内存惟一的访问方式是通过指针间接地访问。<br /><br />第二种：int *pia = new int[ 4 ];&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; 分配了一个含有四个整数元素的数组。<br /><br />&nbsp;&nbsp;&nbsp; 当用完了动态分配的对象或对象的数组时，我们必须显式地释放这些内存。我们可以通过使用delete 表达式来完成这件事情。而释放之后的内存则可以被程序重新使用。<br />&nbsp;&nbsp;&nbsp; 单一对象的delete 表达式形式如下 <br />//&nbsp; 删除单个对象 <br />delete pint; <br />&nbsp;&nbsp;&nbsp;&nbsp; 数组形式的delete 表达式如下 <br />//&nbsp; 删除一个对象数组 <br />delete [] pia; <br />&nbsp;&nbsp;&nbsp;&nbsp; 如果忘了删除动态分配的内存又会怎么样呢？如果真的如此程序就会在结束时出现内存泄漏的问题。<br /><br /></p><img src ="http://www.cppblog.com/linzheng/aggbug/182206.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/linzheng/" target="_blank">linzheng</a> 2012-07-08 14:51 <a href="http://www.cppblog.com/linzheng/archive/2012/07/08/182206.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++基础（2）数组</title><link>http://www.cppblog.com/linzheng/archive/2012/07/08/182205.html</link><dc:creator>linzheng</dc:creator><author>linzheng</author><pubDate>Sun, 08 Jul 2012 06:29:00 GMT</pubDate><guid>http://www.cppblog.com/linzheng/archive/2012/07/08/182205.html</guid><wfw:comment>http://www.cppblog.com/linzheng/comments/182205.html</wfw:comment><comments>http://www.cppblog.com/linzheng/archive/2012/07/08/182205.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/linzheng/comments/commentRss/182205.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/linzheng/services/trackbacks/182205.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; &nbsp;数组array 是一种顺序容器它包含单一类型的元素例如序列：<br />0 1 1 2 3 5 8 13 21 <br />&nbsp;&nbsp;&nbsp;&nbsp; 代表菲波那契数列的前9 个数，只要给出最前面两个元素后面的元素依次可以由前面两个元素相加得出，为了定义和初始化一个数组以便存放这些数我们可以这样写：<br />int fibon[ 9 ] = { 0, 1, 1, 2, 3, 5, 8, 13, 21 }; <br />&nbsp;&nbsp;&nbsp; 虽然C++ 对数组类型提供了内置支持，但是这种支持仅限于用来读写&#8220;单个元素&#8221;的机制。C++ 不支持数组的抽象abstraction，也不支持对整个数组的操作我们有时会希望对整个数组进行操作，例如把一个数组赋值给另外一个数组，对两个数组进行相等比较或者想知道数组的大小size。例如给出两个数组我们不能用赋值操作符把一个数组拷 贝到另一个中去&nbsp;<br />&nbsp;int array0[ 10 ], array1[ 10 ];&nbsp;<br />&nbsp;//&nbsp; 错误不能直接把一个数组赋值给另一个数组 <br />array0 = array1;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; 如果我们希望把一个数组赋值给另外一个则必须自己写程序按顺序拷贝每个元素&nbsp;<br />&nbsp;for ( int index = 0; index &lt; 10; ++index ) <br />&nbsp; array0[ index ] = array1[ index ];&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; 而且数组类型本身没有自我意识，它不知道自己的长度，我们必须另外记录数组本身的这些信息。当我们希望把数组作为一个参数传递给一个函数的时候，问题就出现了。<img src ="http://www.cppblog.com/linzheng/aggbug/182205.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/linzheng/" target="_blank">linzheng</a> 2012-07-08 14:29 <a href="http://www.cppblog.com/linzheng/archive/2012/07/08/182205.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>