﻿<?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++博客-Mycode.h-文章分类-开发者</title><link>http://www.cppblog.com/mtysblog/category/15935.html</link><description>just for coding</description><language>zh-cn</language><lastBuildDate>Sat, 05 Feb 2011 03:44:29 GMT</lastBuildDate><pubDate>Sat, 05 Feb 2011 03:44:29 GMT</pubDate><ttl>60</ttl><item><title>[z]堆、栈及静态数据区详解</title><link>http://www.cppblog.com/mtysblog/articles/139722.html</link><dc:creator>_飞寒</dc:creator><author>_飞寒</author><pubDate>Fri, 04 Feb 2011 08:24:00 GMT</pubDate><guid>http://www.cppblog.com/mtysblog/articles/139722.html</guid><wfw:comment>http://www.cppblog.com/mtysblog/comments/139722.html</wfw:comment><comments>http://www.cppblog.com/mtysblog/articles/139722.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mtysblog/comments/commentRss/139722.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mtysblog/services/trackbacks/139722.html</trackback:ping><description><![CDATA[<p>五大内存分区<br>&nbsp;&nbsp;&nbsp; 在C++中，内存分成5个区，他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。<br>&nbsp;&nbsp;&nbsp; 栈，就是那些由编译器在需要的时候分配，在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。<br>&nbsp;&nbsp;&nbsp; 堆，就是那些由new分配的内存块，他们的释放编译器不去管，由我们的应用程序去控制，一般一个new就要对应一个delete。如果程序员没有释放掉，那么在程序结束后，操作系统会自动回收。<br>&nbsp;&nbsp;&nbsp; 自由存储区，就是那些由malloc等分配的内存块，他和堆是十分相似的，不过它是用free来结束自己的生命的。<br>&nbsp;&nbsp;&nbsp; 全局/静态存储区，全局变量和静态变量被分配到同一块内存中，在以前的C语言中，全局变量又分为初始化的和未初始化的，在C++里面没有这个区分了，他们共同占用同一块内存区。<br>&nbsp;&nbsp;&nbsp; 常量存储区，这是一块比较特殊的存储区，他们里面存放的是常量，不允许修改（当然，你要通过非正当手段也可以修改，而且方法很多）<br>明确区分堆与栈<br>&nbsp;&nbsp;&nbsp; 在bbs上，堆与栈的区分问题，似乎是一个永恒的话题，由此可见，初学者对此往往是混淆不清的，所以我决定拿他第一个开刀。<br>&nbsp;&nbsp;&nbsp; 首先，我们举一个例子：<br>&nbsp;&nbsp;&nbsp; void f() { int* p=new int[5]; } <br>&nbsp;&nbsp;&nbsp; 这条短短的一句话就包含了堆与栈，看到new，我们首先就应该想到，我们分配了一块堆内存，那么指针p呢？他分配的是一块栈内存，所以这句话的意思就是： 在栈内存中存放了一个指向一块堆内存的指针p。在程序会先确定在堆中分配内存的大小，然后调用operator new分配内存，然后返回这块内存的首地址，放入栈中，他在VC6下的汇编代码如下：<br>&nbsp;&nbsp;&nbsp; 00401028&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 14h<br>&nbsp;&nbsp;&nbsp; 0040102A&nbsp;&nbsp; call&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; operator new (00401060)<br>&nbsp;&nbsp;&nbsp; 0040102F&nbsp;&nbsp; add&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; esp,4<br>&nbsp;&nbsp;&nbsp; 00401032&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebp-8],eax<br>&nbsp;&nbsp;&nbsp; 00401035&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eax,dword ptr [ebp-8]<br>&nbsp;&nbsp;&nbsp; 00401038&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebp-4],eax<br>&nbsp;&nbsp;&nbsp; 这里，我们为了简单并没有释放内存，那么该怎么去释放呢？是delete p么？澳，错了，应该是delete []p，这是为了告诉编译器：我删除的是一个数组，VC6就会根据相应的Cookie信息去进行释放内存的工作。<br>&nbsp;&nbsp;&nbsp; 好了，我们回到我们的主题：堆和栈究竟有什么区别？ <br>&nbsp;&nbsp;&nbsp; 主要的区别由以下几点：<br>&nbsp;&nbsp;&nbsp; 1、管理方式不同；<br>&nbsp;&nbsp;&nbsp; 2、空间大小不同；<br>&nbsp;&nbsp;&nbsp; 3、能否产生碎片不同；<br>&nbsp;&nbsp;&nbsp; 4、生长方向不同；<br>&nbsp;&nbsp;&nbsp; 5、分配方式不同；<br>&nbsp;&nbsp;&nbsp; 6、分配效率不同；<br>&nbsp;&nbsp;&nbsp; 管理方式：对于栈来讲，是由编译器自动管理，无需我们手工控制；对于堆来说，释放工作由程序员控制，容易产生memory leak。<br>&nbsp;&nbsp;&nbsp; 空间大小：一般来讲在32位系统下，堆内存可以达到4G的空间，从这个角度来看堆内存几乎是没有什么限制的。但是对于栈来讲，一般都是有一定的空间大小的，例如，在VC6下面，默认的栈空间大小是1M（好像是，记不清楚了）。当然，我们可以修改：&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; 打开工程，依次操作菜单如下：Project-&gt;Setting-&gt;Link，在Category 中选中Output，然后在Reserve中设定堆栈的最大值和commit。<br>注意：reserve最小值为4Byte；commit是保留在虚拟内存的页文件里面，它设置的较大会使栈开辟较大的值，可能增加内存的开销和启动时间。<br>&nbsp;&nbsp;&nbsp; 碎片问题：对于堆来讲，频繁的new/delete势必会造成内存空间的不连续，从而造成大量的碎片，使程序效率降低。对于栈来讲，则不会存在这个问题， 因为栈是先进后出的队列，他们是如此的一一对应，以至于永远都不可能有一个内存块从栈中间弹出，在他弹出之前，在他上面的后进的栈内容已经被弹出，详细的 可以参考数据结构，这里我们就不再一一讨论了。<br>&nbsp;&nbsp;&nbsp; 生长方向：对于堆来讲，生长方向是向上的，也就是向着内存地址增加的方向；对于栈来讲，它的生长方向是向下的，是向着内存地址减小的方向增长。<br>&nbsp;&nbsp;&nbsp; 分配方式：堆都是动态分配的，没有静态分配的堆。栈有2种分配方式：静态分配和动态分配。静态分配是编译器完成的，比如局部变量的分配。动态分配由alloca函数进行分配，但是栈的动态分配和堆是不同的，他的动态分配是由编译器进行释放，无需我们手工实现。<br>&nbsp;&nbsp;&nbsp; 分配效率：栈是机器系统提供的数据结构，计算机会在底层对栈提供支持：分配专门的寄存器存放栈的地址，压栈出栈都有专门的指令执行，这就决定了栈的效率比 较高。堆则是C/C++函数库提供的，它的机制是很复杂的，例如为了分配一块内存，库函数会按照一定的算法（具体的算法可以参考数据结构/操作系统）在堆 内存中搜索可用的足够大小的空间，如果没有足够大小的空间（可能是由于内存碎片太多），就有可能调用系统功能去增加程序数据段的内存空间，这样就有机会分 到足够大小的内存，然后进行返回。显然，堆的效率比栈要低得多。<br>&nbsp;&nbsp;&nbsp; 从这里我们可以看到，堆和栈相比，由于大量new/delete的使用，容易造成大量的内存碎片；由于没有专门的系统支持，效率很低；由于可能引发用户态 和核心态的切换，内存的申请，代价变得更加昂贵。所以栈在程序中是应用最广泛的，就算是函数的调用也利用栈去完成，函数调用过程中的参数，返回地址， EBP和局部变量都采用栈的方式存放。所以，我们推荐大家尽量用栈，而不是用堆。<br>&nbsp;&nbsp;&nbsp; 虽然栈有如此众多的好处，但是由于和堆相比不是那么灵活，有时候分配大量的内存空间，还是用堆好一些。<br>&nbsp;&nbsp;&nbsp; 无论是堆还是栈，都要防止越界现象的发生（除非你是故意使其越界），因为越界的结果要么是程序崩溃，要么是摧毁程序的堆、栈结构，产生以想不到的结果,就 算是在你的程序运行过程中，没有发生上面的问题，你还是要小心，说不定什么时候就崩掉，那时候debug可是相当困难的：）<br>&nbsp;&nbsp;&nbsp; 对了，还有一件事，如果有人把堆栈合起来说，那它的意思是栈，可不是堆，呵呵，清楚了？<br>static用来控制变量的存储方式和可见性<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 函数内部定义的变量，在程序执行到它的定义处时，编译器为它在栈上分配空间，函数在栈上分配的空间在此函数执行结束时会释放掉，这样就产生了一个问题: 如果想将函数中此变量的值保存至下一次调用时，如何实现？ 最容易想到的方法是定义一个全局的变量，但定义为一个全局变量有许多缺点，最明显的缺点是破坏了此变量的访问范围（使得在此函数中定义的变量，不仅仅受此 函数控制）。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 需要一个数据对象为整个类而非某个对象服务,同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部，对外不可见。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static的内部机制：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 静态数据成员要在程序一开始运行时就必须存在。因为函数在程序运行中被调用，所以静态数据成员不能在任何函数内分配空间和初始化。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这样，它的空间分配有三个可能的地方，一是作为类的外部接口的头文件，那里有类声明；二是类定义的内部实现，那里有类的成员函数定义；三是应用程序的main（）函数前的全局数据声明和定义处。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 静态数据成员要实际地分配空间，故不能在类的声明中定义（只能声明数据成员）。类声明只声明一个类的&#8220;尺寸和规格&#8221;，并不进行实际的内存分配，所以在类声 明中写成定义是错误的。它也不能在头文件中类声明的外部定义，因为那会造成在多个使用该类的源文件中，对其重复定义。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static被引入以告知编译器，将变量存储在程序的静态存储区而非栈上空间，静态<br>数据成员按定义出现的先后顺序依次初始化，注意静态成员嵌套时，要保证所嵌套的成员已经初始化了。消除时的顺序是初始化的反顺序。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static的优势：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 可以节省内存，因为它是所有对象所公有的，因此，对多个对象来说，静态数据成员只存储一处，供所有对象共用。静态数据成员的值对每个对象都是一样，但它的 值是可以更新的。只要对静态数据成员的值更新一次，保证所有对象存取更新后的相同的值，这样可以提高时间效率。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 引用静态数据成员时，采用如下格式：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;类名&gt;::&lt;静态成员名&gt;<br>&nbsp;&nbsp;&nbsp; 如果静态数据成员的访问权限允许的话(即public的成员)，可在程序中，按上述格式<br>来引用静态数据成员。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PS:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1)类的静态成员函数是属于整个类而非类的对象，所以它没有this指针，这就导致<br>了它仅能访问类的静态数据和静态成员函数。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)不能将静态成员函数定义为虚函数。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3)由于静态成员声明于类中，操作于其外，所以对其取地址操作，就多少有些特殊<br>，变量地址是指向其数据类型的指针 ，函数地址类型是一个&#8220;nonmember函数指针&#8221;。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4)由于静态成员函数没有this指针，所以就差不多等同于nonmember函数，结果就<br>产生了一个意想不到的好处：成为一个callback函数，使得我们得以将C++和C-based X W<br>indow系统结合，同时也成功的应用于线程函数身上。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (5)static并没有增加程序的时空开销，相反她还缩短了子类对父类静态成员的访问<br>时间，节省了子类的内存空间。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6)静态数据成员在&lt;定义或说明&gt;时前面加关键字static。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (7)静态数据成员是静态存储的，所以必须对它进行初始化。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (8)静态成员初始化与一般数据成员初始化不同:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 初始化在类体外进行，而前面不加static，<br>以免与一般静态变量或对象相混淆；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 初始化时不加该成员的访问权限控制符private，public等；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 初始化时使用作用域运算符来标明它所属类；<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 所以我们得出静态数据成员初始化的格式：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;数据类型&gt;&lt;类名&gt;::&lt;静态数据成员名&gt;=&lt;值&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (9)为了防止父类的影响，可以在子类定义一个与父类相同的静态变量，以屏蔽父类的影响。这里有一点需要注意：我们说静态成员为父类和子类共享，但我们有 重复定义了静态成员，这会不会引起错误呢？不会，我们的编译器采用了一种绝妙的手法：name-mangling 用以生成唯一的标志。</p>
<p>本文来自CSDN博客，转载请标明出处：<a href="http://blog.csdn.net/chenyq2008/archive/2008/09/27/2990070.aspx">http://blog.csdn.net/chenyq2008/archive/2008/09/27/2990070.aspx</a></p>
<img src ="http://www.cppblog.com/mtysblog/aggbug/139722.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mtysblog/" target="_blank">_飞寒</a> 2011-02-04 16:24 <a href="http://www.cppblog.com/mtysblog/articles/139722.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[z] 用 Eclipse 平台进行 C/C++ 开发</title><link>http://www.cppblog.com/mtysblog/articles/139483.html</link><dc:creator>_飞寒</dc:creator><author>_飞寒</author><pubDate>Thu, 27 Jan 2011 11:48:00 GMT</pubDate><guid>http://www.cppblog.com/mtysblog/articles/139483.html</guid><wfw:comment>http://www.cppblog.com/mtysblog/comments/139483.html</wfw:comment><comments>http://www.cppblog.com/mtysblog/articles/139483.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/mtysblog/comments/commentRss/139483.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/mtysblog/services/trackbacks/139483.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
<h1>用 Eclipse 平台进行 C/C++ 开发</h1>
<p><strong><font color=#666666 size=2 face=Verdana>如何使用 C/C++ 开发工具箱（CDT）</font></strong></p>
<div class="ibm-container-body ibm-two-column">
<div class="ibm-column ibm-first">
<div class=author><a class=dwauthor title="" href="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/#author1" rel=#authortip1 jQuery1296103079927="22" hoverIntent_t="undefined"><u><font color=#4c6e94>Pawel Leszek</font></u></a> (<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#112;&#97;&#119;&#101;&#108;&#46;&#108;&#101;&#115;&#122;&#101;&#107;&#64;&#105;&#112;&#103;&#97;&#116;&#101;&#46;&#112;&#108;&#63;&#115;&#117;&#98;&#106;&#101;&#99;&#116;&#61;&#29992;&#32;&#69;&#99;&#108;&#105;&#112;&#115;&#101;&#32;&#24179;&#21488;&#36827;&#34892;&#32;&#67;&#47;&#67;&#43;&#43;&#32;&#24320;&#21457;&#38;&#97;&#109;&#112;&#59;&#97;&#109;&#112;&#59;&#99;&#99;&#61;"><u><font color=#4c6e94>pawel.leszek@ipgate.pl</font></u></a>), 独立软件顾问</div>
<div style="DISPLAY: none" id=authortip1 class="dwauthor-onload-state ibm-no-print" jQuery1296103079927="21">Pawel Leszek 是 <a href="http://www.studiob.com/"><u><font color=#4c6e94>Studio B</font></u></a> 的一位作家，他是一位专长于 Linux/Win/Mac OS 系统体系结构和管理的独立软件顾问和作家。他具有许多操作系统、编程语言和网络协议方面的经验，尤其是 Lotus Domino 和 DB2 方面的经验。Pawel 还是 <em>LinuxWorld</em>上一系列文章的作者，以及 <em>PC World</em>波兰版的 Linux 专栏作家。Pawel 和他的妻子以及可爱的小女儿住在华沙。欢迎提问并提出意见；您可以直接给作者发电子邮件（ <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#112;&#97;&#119;&#101;&#108;&#46;&#108;&#101;&#115;&#122;&#101;&#107;&#64;&#105;&#112;&#103;&#97;&#116;&#101;&#46;&#112;&#108;&#63;&#99;&#99;&#61;"><u><font color=#4c6e94>pawel.leszek@ipgate.pl</font></u></a>）。 </div>
<p>&nbsp;</p>
<p><strong>简介：</strong>&nbsp;我们将概述如何在 C/C++ 开发项目中使用 Eclipse 平台。尽管 Eclipse 主要是一个 Java 开发环境，但其体系结构确保了对其它编程语言的支持。在本文中，您将学习如何使用 C/C++ 开发工具箱（C/C++ Development Toolkit，CDT），它是可用于 Eclipse 的最佳 C/C++ 工具箱。</p>
<!--
<p class="ibm-no-print">
<div id="dw-tag-this" class="ibm-no-print"></div>
<div id="interestShow" class="ibm-no-print"></div>
</p>
-->
<div id=dw-tag-content class=ibm-no-print></div>
<div id=dw-moretags-access class=ibm-access></div>
<p class=ibm-no-print>
<div id=dw-tag-this class=ibm-no-print><a class=ibm-external-link onclick="jQuery.launchTagThisWindow(); return false;" href="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/#"><strong><font color=#4c6e94 size=2 face=Arial>标记本文！</font></strong></a></div>
<div id=interestShow class=ibm-no-print><strong><font color=#4c6e94 size=2 face=Arial></font></strong></div>
<p><strong><font color=#4c6e94 size=2 face=Arial></font></strong></p>
</div>
<div class="ibm-column ibm-second">
<p class=leading><strong>发布日期：</strong>&nbsp;2004 年 3 月 09 日 <br><strong>级别：</strong>&nbsp;初级 <br><strong>访问情况</strong>&nbsp;11865 次浏览 <br><strong>建议:</strong>&nbsp;<span id=nCmts>0&nbsp;(<a href="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/#icomments"><u><font color=#4c6e94>添加评论</font></u></a>)</span> <!-- Rating_Area_Begin --><!-- Ensure that div id is based on input id and ends with -widget --><input id=art-rating value=4 type=hidden name=ratinga></p>
<div id=art-rating-widget jQuery1296103079927="31"><a href="javascript:void(0);" jQuery1296103079927="26"><img title="点击评分 1 星" alt="1 star" src="http://www.ibm.com/developerworks/js/artrating/avg-star-on.gif" width=20 height=20></a><a href="javascript:void(0);" jQuery1296103079927="27"><img title="点击评分 2 星" alt="2 stars" src="http://www.ibm.com/developerworks/js/artrating/avg-star-on.gif" width=20 height=20></a><a href="javascript:void(0);" jQuery1296103079927="28"><img title="点击评分 3 星" alt="3 stars" src="http://www.ibm.com/developerworks/js/artrating/avg-star-on.gif" width=20 height=20></a><a href="javascript:void(0);" jQuery1296103079927="29"><img title="点击评分 4 星" alt="4 stars" src="http://www.ibm.com/developerworks/js/artrating/avg-star-on.gif" width=20 height=20></a><a href="javascript:void(0);" jQuery1296103079927="30"><img title="点击评分 5 星" alt="5 stars" src="http://www.ibm.com/developerworks/js/artrating/star-off.gif" width=20 height=20></a><span id=rateTxt><font size=2 face=Arial> 平均分 （共 6 个评分 ）</font></span></div>
<script language=JavaScript type=text/javascript>
// <![cdata[
//  widget div id and article id as args
window.artRating.init('art-rating-widget');
// ]]&gt;
</script><!-- Rating_Area_End -->
<p><font size=2 face=Arial></font></p>
</div>
</div>
<!-- dW_Summary_Area_END --><!-- CONTENT_BODY -->
<div id=ibm-content-body><!-- MAIN_COLUMN_BEGIN -->
<div id=ibm-content-main><!-- Related_Searches_Area_And_Overlays_Begin --><!-- MAIN_COLUMN_CONTAINER_BEGIN -->
<div class=ibm-container><!-- MAIN_COLUMN_CONTENT_BEGIN -->
<p>C 和 C++ 语言都是世界上最流行且使用最普遍的编程语言，因此 Eclipse 平台（Eclipse Platform）提供对 C/C++ 开发的支持一点都不足为奇。因为 Eclipse 平台只是用于开发者工具的一个框架，它不直接支持 C/C++；它使用外部插件来提供支持。本文将向您演示如何使用 CDT — 用于 C/C++ 开发的一组插件。CDT 项目（有关链接，请参阅本文后面的 <a href="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/#resources"><u><font color=#4c6e94>参考资料</font></u></a>一节）致力于为 Eclipse 平台提供功能完全的 C/C++ 集成开发环境（Integrated Development Environment，IDE）。虽然该项目的重点是 Linux，但它在可使用 GNU 开发者工具的所有环境（包括 Win32（Win 95/98/Me/NT/2000/XP）、QNX Neutrino 和 Solaris 平台）中都能工作。 </p>
<p>CDT 是完全用 Java 实现的开放源码项目（根据 Common Public License 特许的），它作为 Eclipse SDK 平台的一组插件。这些插件将 C/C++ 透视图添加到 Eclipse 工作台（Workbench）中，现在后者可以用许多视图和向导以及高级编辑和调试支持来支持 C/C++ 开发。</p>
<p>由于其复杂性，CDT 被分成几个组件，它们都采用独立插件的形式。每个组件都作为一个独立自主的项目进行运作，有它自己的一组提交者、错误类别和邮件列表。但是，所有插件都是 CDT 正常工作所必需的。下面是 CDT 插件／组件的完整列表：</p>
<ul>
    <li><strong>主 CDT 插件（Primary CDT plug-in）</strong>是&#8220;框架&#8221;CDT 插件。
    <li><strong>CDT 功能 Eclipse（CDT Feature Eclipse）</strong>是 CDT 功能组件（Feature Component）。
    <li><strong>CDT 核心（CDT Core）</strong>提供了核心模型（Core Model）、CDOM 和核心组件（Core Component）。
    <li><strong>CDT UI</strong>是核心 UI、视图、编辑器和向导。
    <li><strong>CDT 启动（CDT Launch）</strong>为诸如编译器和调试器之类的外部工具提供了启动机制。
    <li><strong>CDT 调试核心（CDT Debug Core）</strong>提供了调试功能。
    <li><strong>CDT 调试 UI（CDT Debug UI）</strong>为 CDT 调试编辑器、视图和向导提供了用户界面。
    <li><strong>CDT 调试 MI（CDT Debug MI）</strong>是用于与 MI 兼容的调试器的应用程序连接器。 </li>
</ul>
<p>现在，让我们研究一下如何在实际应用程序中使用这些组件。图 1 显示了 Eclipse 中的 C/C++ 项目：</p>
<br><a name=N1008A><strong><font size=2 face=Arial>图 1. 在带有 CDT 插件的 Eclipse 中编辑 C/C++ 项目</font></strong></a><br><font size=2 face=Arial><img alt="图 1. 在带有 CDT 插件的 Eclipse 中编辑 C/C++ 项目" src="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/workspace.jpg" width=580 height=418></font> <br>
<p><a name=N1009A><span class=atitle><strong><font size=5>安装和运行 CDT</font></strong></span></a></p>
<p>在下载和安装 CDT 之前，首先必需确保 GNU C 编译器（GNU C compiler，GCC）以及所有附带的工具（make、binutil 和 GDB）都是可用的。如果正在运行 <em>Linux</em>，只要通过使用适用于您分发版的软件包管理器来安装开发软件包。在 <em>Windows</em>平台上，将需要安装 Cygwin 工具箱（请参阅 <a href="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/#resources"><u><font color=#4c6e94>参考资料</font></u></a>以获得链接）。Cygwin 是用于 Windows 的类 UNIX 环境，它包括 GCC 移植以及所有必需的开发工具，包括 automake 和 GNU 调试器（GNU Debugger，GDB）。Cygwin 是在 <code>cygwin1.dll</code> 库基础上构建的。Cygwin 的备用解决方案是 Minimalist GNU for Windows（MinGW）（请参阅 <a href="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/#resources"><u><font color=#4c6e94>参考资料</font></u></a>以获得链接）。该工具是一组可免费获取、自由分发的特定于 Windows 的头文件和导入库，这些头文件和导入库与 GNU 工具集（它们允许您生成不依赖于任何第三方 DLL 的本机 Windows 程序）结合在一起。如果您想要创建与 POSIX 兼容的 Windows 应用程序，那么 MinGW 是最佳选择。MinGW 甚至可以在 Cygwin 安装之上工作。 <em>Solaris</em>和 <em>QNX</em>要求您从因特网下载并安装其特定的 GCC、GNU Make binutils 和 GDB 移植（请参阅 <a href="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/#resources"><u><font color=#4c6e94>参考资料</font></u></a>以获得链接）。 </p>
<p>假设您安装了适当的 Java SDK/JRE 和 Eclipse 平台 SDK，并且它们都正常运行。CDT 以两种&#8220;方式&#8221;可用：稳定的发行版和试运行版（nightly build）。试运行版未经完全测试，但它们提供了更多的功能并改正了当前错误。安装之前，请检查磁盘上是否存在先前版本的 CDT，如果存在，请确保完全除去它。因为 CDT 没有可用的卸载程序，所以需要手工除去它。为了检查先前版本是否存在，转至 CDT 插件所驻留的目录： <code>eclipse/plugins</code> 。接着，除去所有以 <code>org.eclipse.cdt</code> 名称开头的目录。需要做的最后一件事情是从 <code>workspace/.metadata/.plugins</code> 和 <code>features</code> 除去 CDT 元数据目录 <code>or.eclipse.cdt.*</code> 。 </p>
<p>下一步是下载 CDT 二进制文件。注意：请下载适合于您操作系统的正确的 CDT。遗憾的是，即使 CDT 是用 Java 编写的，它也不是与平台无关的。接着，将归档文件解压到临时目录中，从临时目录将所有插件目录内容都移到 Eclipse <code>plugins</code> 子目录。还需要将 <code>features</code> 目录内容移到 Eclipse <code>features</code> 子目录中。现在，重新启动 Eclipse。Eclipse 再次启动之后，更新管理器将告诉您它发现了更改并询问您是否确认这些更改。现在您将能够看到两个可用的新项目：C 和 C++。 </p>
<div class=ibm-alternate-rule>
<hr>
</div>
<p class="ibm-ind-link ibm-back-to-top"><a class=ibm-anchor-up-link href="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/#ibm-pcon"><font color=#4c6e94><strong>回页首</strong></font></a></p>
<p><a name=N100E5><span class=atitle><strong><font size=5>创建新项目</font></strong></span></a></p>
<p>在 Eclipse 中安装 CDT 之后，浏览至 <strong>File =&gt; New =&gt; Project</strong>，在那里，您将发现三个新的可用项目类型：C（&#8220;Standard C Make Project&#8221;）、C++（&#8220;Standard C++ Make Project&#8221;）和&#8220;Convert to C or C++ Projects&#8221;。从&#8220;Standard Make C++ Project&#8221;开始，为您的项目创建源代码文件。在 C/C++ Projects 视图中，单击鼠标右键，然后选择 <strong>New =&gt; Simple =&gt; File</strong>。命名您的文件并保存它。您可能会用这种方法创建许多头文件以及 C/C++ 实现代码文件。最后当然是 Makefile，GNU Make 将使用它来构建二进制文件。对该 Makefile 使用常见的 GNU make 语法（请参阅 <a href="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/#resources"><u><font color=#4c6e94>参考资料</font></u></a>）。请记住：Makefile 要求您使用 Tab 字符而不是空格来产生缩进行。 </p>
<p>您通常会将现有的源代码导入 Eclipse（请参阅图 2）。CDT 为执行这一操作提供了一种便捷的方法：即使用 Import 向导，将文件从文件系统目录复制到工作台。转至主菜单栏，选择 <strong>File =&gt; Import =&gt; File System</strong>。单击 <strong>Next</strong>，打开源目录，选择您想要添加文件的目录。单击 <strong>Select All</strong> 以选择目录中的所有资源，然后从头到尾检查，取消选择您不打算添加的那些资源。指定将作为导入目标的工作台项目或文件夹。还可以通过从文件系统拖动文件夹和文件并将它们放入 Navigator 视图中，或者通过复制和粘贴来导入文件夹和文件。 </p>
<br><a name=N10106><strong><font size=2 face=Arial>图 2. 将现有的源代码导入 CDT 项目</font></strong></a><br><font size=2 face=Arial><img alt="图 2. 将现有的源代码导入 CDT 项目" src="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/importing.jpg" width=462 height=480></font> <br>
<div class=ibm-alternate-rule>
<hr>
</div>
<p class="ibm-ind-link ibm-back-to-top"><a class=ibm-anchor-up-link href="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/#ibm-pcon"><font color=#4c6e94><strong>回页首</strong></font></a></p>
<p><a name=N10115><span class=atitle><strong><font size=5>关键的 CDT IDE 功能</font></strong></span></a></p>
<p>CDT IDE 是在 CDT UI 插件所提供的通用可扩展编辑器基础上构建的。然而，该模块仍处于开发阶段，所以它仍缺少一些重要的实用程序，如类浏览器或语言文档浏览器。CDT IDE 的主要功能是：</p>
<ul>
    <li><strong>语法突出显示</strong>：CDT IDE 识别 C/C++ 语法，并为语法突出显示提供了完全可配置的代码着色以及代码格式化功能： </li>
</ul>
<br><a name=N10129><strong><font size=2 face=Arial>图 3. 不成功的编译之后突出显示的语法错误标记</font></strong></a><br><font size=2 face=Arial><img alt="图 3. 不成功的编译之后突出显示的语法错误标记" src="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/error.jpg" width=580 height=418></font> <br>
<ul>
    <li><strong>提纲</strong>：Outline 窗口模块提供了有关出现在源代码中的过程、变量、声明以及函数的快速视图。利用 outline，您可以方便地找到源代码中的适当引用，或者甚至搜索所有项目源代码。
    <li><strong>代码辅助</strong>：这个代码完成功能类似于可在 Borland C++ Builder 或 MS Visual Studio 中找到的功能。它使用了 <em>代码模板</em>，并且只有助于避免愚蠢的语法错误： </li>
</ul>
<br><a name=N1014D><strong><font size=2 face=Arial>图 4. 有助于使用正确的语言语法的代码辅助功能</font></strong></a><br><font size=2 face=Arial><img alt="图 4. 有助于使用正确的语言语法的代码辅助功能" src="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/assist.jpg" width=580 height=301></font> <br>
<ul>
    <li><strong>代码模板</strong>：由代码辅助功能使用的代码模板是标准 C/C++ 语言语法结构的定义。您也可以定义自己的代码模板来扩展您自己的快捷键，如用于 <code>author</code> 或 <code>date</code> 关键字的快捷键。在 <strong>Window =&gt; Preferences =&gt; C/C++ =&gt; Code Templates</strong> 中，可以添加新模板并查看完整的模板列表。也可以将模板作为 XML 文件导出和导入。 </li>
</ul>
<p><a name=figure5><strong>图 5. 预定义的 C/C++ 代码模板</strong> </a><br><img alt="图 5. 预定义的 C/C++ 代码模板" src="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/templates.jpg" width=580 height=434> </p>
<ul>
    <li><strong>代码历史记录</strong>：即使您没有使用 CVS 或其它源代码版本管理软件，也可以跟踪项目源代码中的本地更改。在选择的文件上单击鼠标右键，从上下文菜单选择 <strong>Compare With =&gt; Local History...</strong>： </li>
</ul>
<br><a name=N10192><strong><font size=2 face=Arial>图 6. 用 Local History 功能检查源代码中的更改</font></strong></a><br><font size=2 face=Arial><img alt="图 6. 用 Local History 功能检查源代码中的更改" src="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/local-history.jpg" width=580 height=430></font> <br>
<div class=ibm-alternate-rule>
<hr>
</div>
<p class="ibm-ind-link ibm-back-to-top"><a class=ibm-anchor-up-link href="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/#ibm-pcon"><font color=#4c6e94><strong>回页首</strong></font></a></p>
<p><a name=N101A2><span class=atitle><strong><font size=5>构建并运行项目</font></strong></span></a></p>
<p>CDT 提供了一种设置项目构建选项的简单方法。CDT 依赖于三个 GNU 工具：GCC、GDB 和 Make。因此，对用于调试的 GDB 或用于编译的 GCC 和 Make 的依赖要求这些应用程序可用于用户想要使用的平台。大多数 Linux（通常和类 POSIX）源代码软件包使用 autoconf 脚本来检查构建环境，所以您必需运行 <code>configure</code> 命令，该命令在编译之前创建&#8220;Makefile&#8221;。CDT 没有提供编辑 autoconf 脚本的方法，所以必需手工编写它们；然而，您可以配置构建选项以在编译之前调用 <code>configure</code> 命令。 </p>
<p>如果通过调用 <code>make</code> 命令来构建项目，那么缺省设置没问题，但是，如果使用一种更复杂的方法进行构建，则必需在 Build Command 文本框中输入适当的命令（例如， <code>make -f make_it_all</code> ）。接下来，在 C/C++ Projects 视图中，选择 <strong>C/C++ project</strong>，然后单击鼠标右键并选择 <strong>Rebuild Project</strong>。所有来自 make、编译器和链接程序的编译消息都被重定向到控制台窗口： </p>
<br><a name=N101C6><strong><font size=2 face=Arial>图 7. 带编译器输出的控制台窗口</font></strong></a><br><font size=2 face=Arial><img alt="图 7. 带编译器输出的控制台窗口" src="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/building.jpg" width=580 height=147></font> <br>
<p>编译成功之后，您或许想要运行您的应用程序。所有用于运行和调试的选项都位于主 Eclipse 菜单的 Run 菜单下。然而，必须在早期定义用于运行项目的选项。可以通过转至主菜单（在那里，有用于运行应用程序的不同概要文件）中的 <strong>Run...</strong> 选项来完成这一步；例如，可以将一个概要文件用于测试目的，而将另一个概要文件用于运行最终版本。另外，可以定义希望要传递给应用程序的参数，或者可以设置环境变量。其它选项用于设置调试选项，例如使用哪个调试器（GNU GDB 或 Cygwin GDB）。图 8 显示了正在为项目创建运行概要文件（run profile）。 </p>
<br><a name=N101DE><strong><font size=2 face=Arial>图 8. 为项目创建运行概要文件</font></strong></a><br><font size=2 face=Arial><img alt="图 8. 为项目创建运行概要文件" src="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/running.jpg" width=580 height=520></font> <br>
<p>当进入 C/C++ Projects 视图，选择您的项目，单击鼠标右键并在 Build Settings 选项卡上选择 <strong>Properties</strong> 之后，就可以使用更多的用于构建项目的常用选项。这些选项主要影响因遇到编译错误而使构建停止时所发生的情况。 </p>
<div class=ibm-alternate-rule>
<hr>
</div>
<p class="ibm-ind-link ibm-back-to-top"><a class=ibm-anchor-up-link href="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/#ibm-pcon"><font color=#4c6e94><strong>回页首</strong></font></a></p>
<p><a name=N101F4><span class=atitle><strong><font size=5>调试 C/C++ 项目</font></strong></span></a></p>
<p>CDT 扩展了标准的 Eclipse Debug 视图，使之具备了调试 C/C++ 代码的功能。Debug 视图允许您在工作台中管理程序的调试或运行。要开始调试当前项目，只要切换到 Debug 视图，您将能够在代码中设置（并在执行过程中随时更改）断点／监测点并跟踪变量和寄存器。Debug 视图显示正在调试的每个目标的暂挂线程的堆栈框架。程序中的每个线程都作为树中的一个节点出现，Debug 视图显示正在运行的每个目标的进程。 </p>
<p>Eclipse 通过 CDT 调试 MI（CDT Debug MI）插件（其组件之一）支持与机器接口（Machine Interface，MI）兼容的调试器。但 MI 调试器究竟是什么呢？通常情况下，象 ddd 和 xxgdb（请参阅 <a href="http://www.ibm.com/developerworks/cn/linux/opensource/os-ecc/#resources"><u><font color=#4c6e94>参考资料</font></u></a>以获得链接）之类的第三方 GUI 调试器在实现调试功能时都依赖于 GDB 的命令行接口（Command Line Interface，CLI）。遗憾的是，经过证实该接口非常不可靠。GDB/MI 提供了一种新的面向机器的接口，它非常适合于想要直接解析 GDB 输出的程序。 </p>
</div>
</div>
</div>
<img src ="http://www.cppblog.com/mtysblog/aggbug/139483.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/mtysblog/" target="_blank">_飞寒</a> 2011-01-27 19:48 <a href="http://www.cppblog.com/mtysblog/articles/139483.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>