﻿<?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++博客-Lori-文章分类-It技能</title><link>http://www.cppblog.com/Lori/category/2441.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 20 May 2008 14:29:48 GMT</lastBuildDate><pubDate>Tue, 20 May 2008 14:29:48 GMT</pubDate><ttl>60</ttl><item><title>vc读取ini</title><link>http://www.cppblog.com/Lori/articles/20559.html</link><dc:creator>张岁滔</dc:creator><author>张岁滔</author><pubDate>Sun, 25 Mar 2007 10:03:00 GMT</pubDate><guid>http://www.cppblog.com/Lori/articles/20559.html</guid><wfw:comment>http://www.cppblog.com/Lori/comments/20559.html</wfw:comment><comments>http://www.cppblog.com/Lori/articles/20559.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Lori/comments/commentRss/20559.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Lori/services/trackbacks/20559.html</trackback:ping><description><![CDATA[例子:backup.ini   <br />  [CONNECTION]   <br />  ServerName="myComputer"   <br />  LoginID="sa"   <br />  password="myPassword"   <br />    <br />  [CMDTIMEOUT]   <br />  TimeOut=50   <br />    <br />  ///////////////////////////////////////////////////   <br />  CString   ServerName;   <br />  CString   Password;   <br />  CString   LoginID;   <br />  int   TimeOut;   <br />    <br />  GetPrivateProfileString("CONNECTION","ServerName",NULL,   <br />  ServerName.GetBuffer(MAX_PATH),MAX_PATH,".//backup.ini");   <br />    <br />  GetPrivateProfileString("CONNECTION","LoginID",NULL,   <br />  LoginID.GetBuffer(MAX_PATH),MAX_PATH,".//backup.ini");   <br />    <br />  GetPrivateProfileString("CONNECTION","Password",NULL,   <br />  password.GetBuffer(MAX_PATH),MAX_PATH,".//backup.ini");   <br />    <br />  TimeOut=GetPrivateProfileInt("CMDTIMEOUT",   <br />  "TimeOut",NULL,".//backup.ini");   
<p> </p><img src ="http://www.cppblog.com/Lori/aggbug/20559.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Lori/" target="_blank">张岁滔</a> 2007-03-25 18:03 <a href="http://www.cppblog.com/Lori/articles/20559.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>建模工具Rose的学习</title><link>http://www.cppblog.com/Lori/articles/17031.html</link><dc:creator>张岁滔</dc:creator><author>张岁滔</author><pubDate>Sat, 30 Dec 2006 05:48:00 GMT</pubDate><guid>http://www.cppblog.com/Lori/articles/17031.html</guid><wfw:comment>http://www.cppblog.com/Lori/comments/17031.html</wfw:comment><comments>http://www.cppblog.com/Lori/articles/17031.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Lori/comments/commentRss/17031.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Lori/services/trackbacks/17031.html</trackback:ping><description><![CDATA[在随着面向对象的程序设计的广泛应用，可视化编程遍地开花的今天，编程工作人员的地位一再被动摇，早以不再作为开发中的主流，而<a class="Channel_KeyLink" href="http://www.qhtx.net/edu/soft">软件</a>工程的应用以作为<a class="Channel_KeyLink" href="http://www.qhtx.net/edu/soft">软件</a>开发的质量和效率的重要见证已越来越被重视，针对早期的结构化建模工具的明显不足，ROSE吸取众多建模工具的优点，排除其不足，采用面向对象的成熟技术和双向工程的技巧，为提高<a class="Channel_KeyLink" href="http://www.qhtx.net/edu/soft">软件</a>开发的效率，保证<a class="Channel_KeyLink" href="http://www.qhtx.net/edu/soft">软件</a>开发的质量和可维护性作出了巨大的贡献。 <br /><a class="Channel_KeyLink" href="http://www.qhtx.net/edu/soft">软件</a>工程概述 <br />　　 <a class="Channel_KeyLink" href="http://www.qhtx.net/edu/soft">软件</a>开发是一套关于<a class="Channel_KeyLink" href="http://www.qhtx.net/edu/soft">软件</a>开发各阶段的定义、任务、作用的建立在理论上的一门工程学科。它为解决<a class="Channel_KeyLink" href="http://www.qhtx.net/edu/soft">软件</a>危机，指导人们利用科学、有效的方法来开发<a class="Channel_KeyLink" href="http://www.qhtx.net/edu/soft">软件</a>，提高及保证<a class="Channel_KeyLink" href="http://www.qhtx.net/edu/soft">软件</a>开发的效率和质量取到了一定的作用。 <a class="Channel_KeyLink" href="http://www.qhtx.net/edu/soft">软件</a>开发过程：需求分析（开始阶段）--概要设计（静态结构）--详细设计（动态结构） --编码-测试-维护 <br />结构化模型设计方法 <br />A．E-R图（实体关系图） <br />　　 实体：客观存在并可区分的事物。 <br />　　 属性：实体所具有的某种特性，一个实体可以有多个属性。 <br />　　 关系：实体之间的对应关系，可分为1：1联系、1：n联系、m：n联系 <br /><img height="530" src="http://zcy.wefine.com/edu/Upload_Edu/200601/200611615118862.gif" width="400" /><br />B．数据流图 <br /><img height="241" src="http://zcy.wefine.com/edu/Upload_Edu/200601/2006116151111735.gif" width="538" /><br />C．功能模块图 <br /><img height="252" src="http://zcy.wefine.com/edu/Upload_Edu/200601/2006116151112691.gif" width="370" /><br />结构化模型的不足 <br />　　 传统的结构化模型的设计所建立的模型不能反应源代码，与程序设计脱节。模型与代码几乎没什么关系。这样的模型不能生成代码，代码更不能生成模型，模型大多是画给领导看或拿出作掩盖。所以不能保证<a class="Channel_KeyLink" href="http://www.qhtx.net/edu/soft">软件</a>的质量，更不易<a class="Channel_KeyLink" href="http://www.qhtx.net/edu/soft">软件</a>的维护，没什么约束力也没有检测的标准，它的弊端是显于易见的。 <br />面向对象的模型设计方法 <br />　　 定义：利用面向对象方法，把应用程序分成许多小块（对象），这些对象是独立的，然后组合这些对象，建立程序。 <br />　　 特点：包装、继承、多态。 <br />　　 常用的建模工具：PlayCase, Rational ROSE, Computer Association BPWin , Computer Association ERWin, Oracle Designer/2000, Sybase PowerDesigner <br />UML语言概述 <br />　　 定义：一种面向对象的统一建模语言。 <br />　　 作用：帮助我们对<a class="Channel_KeyLink" href="http://www.qhtx.net/edu/soft">软件</a>系统进行面向对象的和建模。 <br />　　 核心：类，类之间的关系。 <br />　　 建模：通过将用户的业务震需求映射为代码，保证代码满足这些需求，代码能方便地回溯需求，这个过程叫建模。 <br />ROSE建模工具 <br />　　 定义：是一种分析和设计面向对象的建模工具。 <br />　　 作用：利用ROSE这个工具，我们可以建立用UML的<a class="Channel_KeyLink" href="http://www.qhtx.net/edu/soft">软件</a>系统的模型，面目可以自动生成和维护C++、JAVA、VB、PB、ORACLE等语言和系统的代码。 <br />　　 核心：七大框图 <br />　　 1. Use-Case Diagrams（用例框图） <br />　　 2. sequence diagram （顺序框图） <br />　　 3. Collaboration diagram （协作框图） <br />　　 4. Class diagram （类框图） <br />　　 5. State Transition diagram （状态框图） <br />　　 6. Component diagram （组件框图） <br />　　 7. Deployment diagram （扩展框图） <br />　　 下面结合<a class="Channel_KeyLink" href="http://www.qhtx.net/edu/soft">软件</a>工程知识、利用ROSE建模工具，本人在开发电力部们的"110KV标准设计图文管理系统"中所用到的ROSE模型及对ROSE在开发实践中的剖析 <br />一、 需求分析阶段 <br />　　 任务：建立用户需求和功能模块，确定系统中的角色和使用案例。利用ROSE，生成角色，使用案例和生成用例图 <br />所用到的框图： <br />　　 1.Use-Case Diagrams：显示使用案例（表示系统功能）与角色（人或系统）间的交互。如下图： <br /><img height="347" src="http://zcy.wefine.com/edu/Upload_Edu/200601/2006116151120825.gif" width="450" /><br />　　 Use Case（用例）：在不展现一个系统或系统内部结构的情况下，对系统或系统的连贯的功能单元的定义和描述。 <br />角色：使用<a class="Channel_KeyLink" href="http://www.qhtx.net/edu/soft">软件</a>的人或外部系统本身。 <br />2. sequence diagram <br />　　 按时间先后顺序，从上到下分析使用案例，确定案例的处理流程。如下图： <br /><img height="566" src="http://zcy.wefine.com/edu/Upload_Edu/200601/2006116151121211.gif" width="493" /><br />3 Collaboration diagram ： <br />　　 确定对象之间的关系的处理过程的分析流程。如下图： <br /><img height="396" src="http://zcy.wefine.com/edu/Upload_Edu/200601/2006116151126546.gif" width="429" /><br />二、 概要设计阶段 <br />　　 任务：通过分析Use-Case Diagrams ，得到所用到的类，分析这些类的属性、操作和它们之间的关系。 <br />　　 所用到的框图： <br />1.Class Diagrams. <br />　　 显示系统中类与类之间的交互。 <br /><img height="338" src="http://zcy.wefine.com/edu/Upload_Edu/200601/2006116151128510.gif" width="203" /><br />2.包：具有一些共性的类组合在一起的图。 <br /><img height="180" src="http://zcy.wefine.com/edu/Upload_Edu/200601/2006116151129434.gif" width="383" /><br /><br />三、 详细设计阶段 <br />　　 任务：细化和个性Use-Case的描述 ，如类的操作和对象之间的消息相对应，填充参数及复杂的类的设计。 <br />　　 所用到的框图： <br />1.Class Diagrams <br />2.State Diagrams:显示一个对象从生成到删除的生命周期。 <br />四、 编码和测试阶段 <br />　　 任务：进行<a class="Channel_KeyLink" href="http://www.qhtx.net/edu/soft">软件</a>的开发和测试，生成组件框图。 <br />　　 组件：表示代码的物理模块。 <br />　　 组件框图：表示系统中的组件及相互依赖性。 <br />　　 Delpoyment Diagrams:显示<a class="Channel_KeyLink" href="http://www.qhtx.net/edu/net/">网络</a>中的物理布局和各种组件的位置。 <br /><img height="231" src="http://zcy.wefine.com/edu/Upload_Edu/200601/2006116151130937.gif" width="511" /><br />双向工程 <br />　　 1.生成代码：根据选择开发应用程序的语言生成对应的程序的代码。 <br />　　 步骤：检查模型-生成组件-将类映射组件-设置代码生成属性-选择类、组件和包-生成代码 <br />　　 2.逆向转出工程：根据选择开发应用程序的语言生成对应的程序的代码。 <br />　　 步骤：检查模型-生成组件-将类映射组件-设置代码生成属性-选择类、组件和包-生成代码 <br />概述 
<p>　　在这个面向对象应用程序开发不断变化的时代，在合理时间内开发和管理高质量应用程序变得越来越困难。为了面对这种挑战，制定出每个公司都能使用的通用对象模型语言，统一建模语言（UML）。UML是信息技术行业的蓝图，是详细描述系统结构的方法。利用这个蓝图，我们越来越容易建立和维护系统，保证系统能适应需求的改变。一个系统的模型建得好，就为满足用户需求、保证系统的稳定性和质量、提高系统的扩展性打下了良好的基础。ROSE是用UML快速开发应用程序的工具之一，它是一个面向对象的建模工具。 </p><p>UML统一建模语言 </p><p>　　UML，Unified Modeling Language，统一建模语言，是一种面向对象的建模语言，它的主要作用是帮助我们对<a class="Channel_KeyLink" href="http://www.qhtx.net/edu/soft"><font color="#002c99">软件</font></a>系统进行面向对象的描述和建模，它可以描述这个<a class="Channel_KeyLink" href="http://www.qhtx.net/edu/soft"><font color="#002c99">软件</font></a>开发过程从需求分析直到实现和测试的全过程。UML通过建立各种类、类之间的关联、类/对象怎样相互配合实现系统的动态行为等成分（这些都称为模型元素）来组建整个模型，刻画客观世界。UML提供了各种图形，比如Use Case图、类图、顺序图、协作图、状态图等，来把这些模型元素及其关系可视化，让人们可以清楚容易的理解模型。我们可以从多个视角来考察模型，从而更加全面的了解模型，这样同一个模型元素可能会出现在多个图中，对应多个图形元素。 <br /></p><p>　　由视图view，图diagram，模型元素model element和通用机制general mechanism等几个部分组成 .视图是表达系统的某一方面特征的UML建模元素的子集，由多个图构成，是在某一个抽象层上，对系统的抽象表示.图是模型元素集的图形表示，通常为弧（关系）和顶点（其他模型元素）相互连接构成的.模型元素代表面向对象中的类、对象、消息和关系等概念，是构成图的最基本的常用概念.通用机制用于表示其它信息，比如注释、模型元素的语义等。另外，它还提供扩展机制，使UML语言能够适应一个特殊的方法（或过程），或扩充至一个组织或用户. <br /></p><p>　　UML是用来描述模型的，用模型来描述系统的结构或静态特征，以及行为或动态特征。从不同的视角为系统的构架建模，形成系统的不同视图（VIEW）。 <br /></p><p>　　用例视图(use case view)，强调从用户的角度看到的或需要的系统功能，是被称为参与者的外部用户所能观察到的系统功能的模型图； <br /></p><p>　　逻辑视图(logical view)，展现系统的静态或结构组成及特征，也称为结构模型视图(structural model view)或静态视图（static view）； <br /></p><p>　　并发视图(concurrent view)，体现了系统的动态或行为特征，也称为行为模型视图（behavioral model view）、动态视图(dynamic view)； <br /></p><p>　　组件视图(component view)，体现了系统实现的结构和行为特征，也称为实现模型视图(implementation model view) ； <br /></p><p>　　配置视图(deployment view)，体现了系统实现环境的结构和行为特征，也称为环境模型视图（environment model view）或物理视图(physical view)。 </p><p>建模工具Rose 之游 </p><p>　　ROSE是美国Rational公司的面向对象建模工具，利用这个工具，我们可以建立用UML描述的<a class="Channel_KeyLink" href="http://www.qhtx.net/edu/soft"><font color="#002c99">软件</font></a>系统的模型，而且可以自动生成和维护C++、Java、VB、Oracle等语言和系统的代码。 <br /></p><p>　　ROSE是个菜单驱动应用程序，用工具栏帮助使用常用特性。它的界面分为三个部分--Browser窗口、Diagram窗口和Document窗口。Browser窗口用来浏览、创建、删除和修改模型中的模型元素；Diagram窗口用来显示和创作模型的各种图；而Document窗口则是用来显示和书写各个模型元素的文档注释。 </p><p align="center"><img height="333" src="http://zcy.wefine.com/edu/Upload_Edu/200601/2006116151139170.gif" width="412" /></p><p align="center">Rose界面 <br /></p><p>　　Rose模型的四个视图是Use Case视图 、Logical视图、Component视图和Deployment视图。每个视图针对不同对象，具有不同用途。Use Case视图包括系统中的所有角色、案例和Use Case图，还包括一些Sequence图和Collaboration图。 <br /></p><p align="center"><img height="280" src="http://zcy.wefine.com/edu/Upload_Edu/200601/2006116151147961.gif" width="181" /></p><p align="center">Use Case视图 <br /></p><p>　　Logical视图关注系统如何实现使用案例中提到的功能。它提供系统的详细图形，描述组件间如何关联。除其它内容之外，Logical视图还包括需要的特定类、Class图和State Transition 图。利用这些细节元素，开发人员可以构造系统的详细设计。 </p><p align="center"><img height="308" src="http://zcy.wefine.com/edu/Upload_Edu/200601/200611615128965.gif" width="181" /></p><p align="center"><br />Logical视图 <br /></p><p>　　Component视图包括模型代码库、执行库和其它组件的信息。组件是代码的实际模块。Component视图的主要用户是负责控制代码和编译部署应用程序的人。有些组件是代码库，有些组件是运行组件，如执行文件或动态链接库（DLL）文件。 <br /></p><p>　　Collaboration图关注系统的部署，可能与系统的逻辑结构不同。整个小组都用Collaboration图了解系统部署，但用户是发布应用程序的人员。 </p><p>Rose的九种图 <br /></p><p>　　用例图use case diagram，描述系统功能 <br />　　 类图class diagram，描述系统的静态结构 <br />　　 对象图object diagram，描述系统在某个时刻的静态结构 <br />　　 序列图sequence diagram，按时间顺序描述系统元素间的交互 <br />　　 协作图Collaboration diagram，按照时间和空间顺序描述系统元素间的交互和它们之间的关系 <br />　　 状态图state diagram，描述了系统元素的状态条件和响应 <br />　　 活动图activity diagram，描述了系统元素的活动 <br />　　 组件图component diagram，描述了实现系统的元素的组织 <br />　　 配置图deployment diagram，描述了环境元素的配置，并把实现系统的元素映射到配置上 <br /></p><p>　　根据它们在不同架构视图的应用，可以把9种图分成： <br /></p><p>　　用户模型视图：用例图 <br />　　 结构模型视图：类图、对象图 <br />　　 行为模型视图：序列图、协作图、状态图、活动图（动态图） <br />　　 实现模型视图：组件图 <br />　　 环境模型视图：配置图 <br /></p><br /><img src ="http://www.cppblog.com/Lori/aggbug/17031.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Lori/" target="_blank">张岁滔</a> 2006-12-30 13:48 <a href="http://www.cppblog.com/Lori/articles/17031.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>STL实践指南 </title><link>http://www.cppblog.com/Lori/articles/17028.html</link><dc:creator>张岁滔</dc:creator><author>张岁滔</author><pubDate>Sat, 30 Dec 2006 04:32:00 GMT</pubDate><guid>http://www.cppblog.com/Lori/articles/17028.html</guid><wfw:comment>http://www.cppblog.com/Lori/comments/17028.html</wfw:comment><comments>http://www.cppblog.com/Lori/articles/17028.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Lori/comments/commentRss/17028.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Lori/services/trackbacks/17028.html</trackback:ping><description><![CDATA[
		<p>译者注<br />这是一篇指导您如何在Microsoft Visual Studio下学习STL并进行实践的文章。这篇文章从STL的基础知识讲起，循序渐进，逐步深入，涉及到了STL编写代码的方法、STL代码的编译和调试、命名空间（namespace）、STL中的ANSI / ISO字符串、各种不同类型的容器（container）、模板（template）、游标（Iterator）、算法（Algorithms）、分配器（Allocator）、容器的嵌套等方面的<a class="Channel_KeyLink" href="http://www.qhtx.net/BBS">问题</a>，作者在这篇文章中对读者提出了一些建议，并指出了使用STL时应该注意的<a class="Channel_KeyLink" href="http://www.qhtx.net/BBS">问题</a>。这篇文章覆盖面广，视角全面。不仅仅适合初学者学习STL，更是广大读者使用STL编程的实践指南。<br /><br />STL简介<br /><br />STL (标准模版库，Standard Template Library)是当今每个从事<a class="Channel_KeyLink" href="http://www.qhtx.net/edu/program/cpp/">C++编程</a>的人需要掌握的一项不错的技术。我觉得每一个初学STL的人应该花费一段时间来熟悉它，比如，学习STL时会有急剧升降的学习曲线，并且有一些命名是不太容易凭直觉就能够记住的（也许是好记的名字已经被用光了），然而如果一旦你掌握了STL，你就不会觉得头痛了。和MFC相比，STL更加复杂和强大。<br />STL有以下的一些优点：<br /><br />可以方便容易地实现搜索数据或对数据排序等一系列的算法；<br /><br />调试程序时更加安全和方便；<br /><br />即使是人们用STL在UNIX平台下写的代码你也可以很容易地理解（因为STL是跨平台的）。<br /><br />背景知识<br /><br />写这一部分是让一些初学计算机的读者在富有挑战性的计算机科学领域有一个良好的开端，而不必费力地了解那无穷无尽的行话术语和沉闷的规则，在这里仅仅把那些行话和规则当作STLer们用于自娱的创造品吧。<br /><br />使用代码<br />本文使用的代码在STL实践中主要具有指导意义。<br /><br />一些基础概念的定义<br /><br />模板（Template）——类（以及结构等各种数据类型和函数）的宏（macro）。有时叫做甜饼切割机（cookie cutter），正规的名称应叫做范型（generic）——一个类的模板叫做范型类（generic class），而一个函数的模板也自然而然地被叫做范型函数（generic function）。<br />STL——标准模板库，一些聪明人写的一些模板，现在已成为每个人所使用的标准C++语言中的一部分。<br />容器（Container）——可容纳一些数据的模板类。STL中有vector，set，map，multimap和deque等容器。<br />向量（Vector）——基本数组模板，这是一个容器。<br />游标（Iterator）——这是一个奇特的东西，它是一个指针，用来指向STL容器中的元素，也可以指向其它的元素。<br /><br />Hello World程序<br /><br />我愿意在我的黄金时间在这里写下我的程序：一个hello world程序。这个程序将一个字符串传送到一个字符向量中，然后每次显示向量中的一个字符。向量就像是盛放变长数组的花园，大约所有STL容器中有一半是基于向量的，如果你掌握了这个程序，你便差不多掌握了整个STL的一半了。<br /><br /><br />//程序：vector演示一<br />//目的：理解STL中的向量<br /><br />// #include "stdafx.h" -如果你使用预编译的头文件就包含这个头文件<br />#include &lt;vector&gt; // STL向量的头文件。这里没有".h"。<br />#include &lt;iostream&gt; // 包含cout对象的头文件。<br />using namespace std; //保证在程序中可以使用std命名空间中的成员。<br /><br />char* szHW = "Hello World";<br /><br />//这是一个字符数组，以”\0”结束。<br /><br />int main(int argc, char* argv[])<br />{<br /> vector &lt;char&gt; vec; //声明一个字符向量vector (STL中的数组) <br /><br /> //为字符数组定义一个游标iterator。<br /> vector &lt;char&gt;::iterator vi;<br /><br /> //初始化字符向量，对整个字符串进行循环，<br /> //用来把数据填放到字符向量中，直到遇到”\0”时结束。<br /> char* cptr = szHW; // 将一个指针指向“Hello World”字符串<br /> while (*cptr != '\0')<br /> { vec.push_back(*cptr); cptr++; }<br /> // push_back函数将数据放在向量的尾部。<br /><br /> // 将向量中的字符一个个地显示在控制台<br /> for (vi=vec.begin(); vi!=vec.end(); vi++) <br /> // 这是STL循环的规范化的开始——通常是 "!=" ， 而不是 "&lt;"<br /> // 因为"&lt;" 在一些容器中没有定义。 <br /> // begin()返回向量起始元素的游标（iterator），end()返回向量末尾元素的游标（iterator）。<br /> { cout &lt;&lt; *vi; } // 使用运算符 “*” 将数据从游标指针中提取出来。<br /> cout &lt;&lt; endl; // 换行<br /><br /> return 0;<br />}<br /><br /><br /><br />push_back是将数据放入vector（向量）或deque（双端队列）的标准函数。Insert是一个与之类似的函数，然而它在所有容器中都可以使用，但是用法更加复杂。end()实际上是取末尾加一（取容器中末尾的前一个元素），以便让循环正确运行——它返回的指针指向最靠近数组界限的数据。就像普通循环中的数组，比如for (i=0; i&lt;6; i++) {ar[i] = i;} ——ar[6]是不存在的，在循环中不会达到这个元素，所以在循环中不会出现<a class="Channel_KeyLink" href="http://www.qhtx.net/BBS">问题</a>。<br /><br />STL的烦恼之一——初始化<br /><br />STL令人烦恼的地方是在它初始化的时候。STL中容器的初始化比C/C++数组初始化要麻烦的多。你只能一个元素一个元素地来，或者先初始化一个普通数组再通过转化填放到容器中。我认为人们通常可以这样做：<br /><br /><br />//程序：初始化演示<br />//目的：为了说明STL中的向量是怎样初始化的。<br /><br />#include &lt;cstring&gt; // &lt;cstring&gt;和&lt;string.h&gt;相同<br />#include &lt;vector&gt;<br />using namespace std;<br /><br />int ar[10] = { 12, 45, 234, 64, 12, 35, 63, 23, 12, 55 };<br />char* str = "Hello World";<br /><br />int main(int argc, char* argv[])<br />{<br /> vector &lt;int&gt; vec1(ar, ar+10);<br /> vector &lt;char&gt; vec2(str, str+strlen(str));<br /> return 0;<br />}<br /><br /><br /><br />在编程中，有很多种方法来完成同样的工作。另一种填充向量的方法是用更加熟悉的方括号，比如下面的程序：<br /><br />//程序：vector演示二<br />//目的：理解带有数组下标和方括号的STL向量<br /><br />#include &lt;cstring&gt;<br />#include &lt;vector&gt;<br />#include &lt;iostream&gt;<br />using namespace std;<br /><br />char* szHW = "Hello World";<br />int main(int argc, char* argv[])<br />{<br /> vector &lt;char&gt; vec(strlen(sHW)); //为向量分配内存空间<br /> int i, k = 0;<br /> char* cptr = szHW;<br /> while (*cptr != '\0')<br /> { vec[k] = *cptr; cptr++; k++; }<br /> for (i=0; i&lt;vec.size(); i++)<br /> { cout &lt;&lt; vec[i]; }<br /> cout &lt;&lt; endl;<br /> return 0;<br />}<br /><br /><br /><br />这个例子更加清晰，但是对游标（iterator）的操作少了，并且定义了额外的整形数作为下标，而且，你必须清楚地在程序中说明为向量分配多少内存空间。<br /><br />命名空间（Namespace）<br /><br />与STL相关的概念是命名空间（namespace）。STL定义在std命名空间中。有3种方法声明使用的命名空间：<br /><br />1．用using关键字使用这个命名空间，在文件的顶部，但在声明的头文件下面加入：<br />using namespace std;<br />这对单个工程来说是最简单也是最好的方法，这个方法可以把你的代码限定在std命名空间中。<br /><br />2．使用每一个模板前对每一个要使用的对象进行声明（就像原形化）：<br />using std::cout;<br />using std::endl;<br />using std::flush;<br />using std::set;<br />using std::inserter;<br />尽管这样写有些冗长，但可以对记忆使用的函数比较有利，并且你可以容易地声明并使用其他命名空间中的成员。<br /><br />3．在每一次使用std命名空间中的模版时，使用std域标识符。比如：<br />typedef std::vector VEC_STR;<br />这种方法虽然写起来比较冗长，但是是在混合使用多个命名空间时的最好方法。一些STL的狂热者一直使用这种方法，并且把不使用这种方法的人视为异类。一些人会通过这种方法建立一些宏来简化<a class="Channel_KeyLink" href="http://www.qhtx.net/BBS">问题</a>。<br /><br />除此之外，你可以把using namespace std加入到任何域中，比如可以加入到函数的头部或一个控制循环体中。<br /><br />一些建议<br /><br />为了避免在调试模式（debug mode）出现恼人的警告，使用下面的编译器命令：<br /><br />#pragma warning(disable: 4786)<br /><br />另一条需要注意的是，你必须确保在两个尖括号之间或尖括号和名字之间用空格隔开，因为是为了避免同“&gt;&gt;”移位运算符混淆。比如<br />vector &gt; veclis;<br />这样写会报错，而这样写：<br />vector &gt; veclis;<br />就可以避免错误。<br />另一种容器——集合（set）<br /><br />这是微软帮助文档中对集合（set）的解释：“描述了一个控制变长元素序列的对象（注：set中的key和value是Key类型的，而map中的key和value是一个pair结构中的两个分量）的模板类，每一个元素包含了一个排序键（sort key）和一个值(value)。对这个序列可以进行查找、插入、删除序列中的任意一个元素，而完成这些操作的时间同这个序列中元素个数的对数成比例关系，并且当游标指向一个已删除的元素时，删除操作无效。”<br />而一个经过更正的和更加实际的定义应该是：一个集合（set）是一个容器，它其中所包含的元素的值是唯一的。这在收集一个数据的具体值的时候是有用的。集合中的元素按一定的顺序排列，并被作为集合中的实例。如果你需要一个键/值对（pair）来存储数据，map是一个更好的选择。一个集合通过一个链表来组织，在插入操作和删除操作上比向量（vector）快，但查找或添加末尾的元素时会有些慢。<br />下面是一个例子：<br /><br />//程序：set演示<br />//目的：理解STL中的集合（set）<br /><br />#include &lt;string&gt;<br />#include &lt;set&gt;<br />#include &lt;iostream&gt;<br />using namespace std;<br /><br />int main(int argc, char* argv[])<br />{<br /> set &lt;string&gt; strset;<br /> set &lt;string&gt;::iterator si;<br /> strset.insert("cantaloupes");<br /> strset.insert("apple");<br /> strset.insert("orange");<br /> strset.insert("banana");<br /> strset.insert("grapes");<br /> strset.insert("grapes"); <br /> for (si=strset.begin(); si!=strset.end(); si++) <br /> { cout &lt;&lt; *si &lt;&lt; " "; }<br /> cout &lt;&lt; endl;<br /> return 0;<br />}<br /><br />// 输出： apple banana cantaloupes grapes orange<br />//注意：输出的集合中的元素是按字母大小顺序排列的，而且每个值都不重复。<br /><br /><br />如果你感兴趣的话，你可以将输出循环用下面的代码替换：<br /><br />copy(strset.begin(), strset.end(), ostream_iterator&lt;string&gt;(cout, " "));<br /><br />.集合（set）虽然更强大，但我个人认为它有些不清晰的地方而且更容易出错，如果你明白了这一点，你会知道用集合（set）可以做什么。<br /><br />所有的STL容器<br /><br />容器（Container）的概念的出现早于模板（template），它原本是一个计算机科学领域中的一个重要概念，但在这里，它的概念和STL混合在一起了。下面是在STL中出现的7种容器：<br /><br />vector（向量）——STL中标准而安全的数组。只能在vector 的“前面”增加数据。<br />deque（双端队列double-ended queue）——在功能上和vector相似，但是可以在前后两端向其中添加数据。 <br />list（列表）——游标一次只可以移动一步。如果你对链表已经很熟悉，那么STL中的list则是一个双向链表（每个节点有指向前驱和指向后继的两个指针）。<br />set（集合）——包含了经过排序了的数据，这些数据的值(value)必须是唯一的。<br />map（映射）——经过排序了的二元组的集合，map中的每个元素都是由两个值组成，其中的key（键值，一个map中的键值必须是唯一的）是在排序或搜索时使用，它的值可以在容器中重新获取；而另一个值是该元素关联的数值。比如，除了可以ar[43] = "overripe"这样找到一个数据，map还可以通过ar["banana"] = "overripe"这样的方法找到一个数据。如果你想获得其中的元素信息，通过输入元素的全名就可以轻松实现。<br />multiset（多重集）——和集合（set）相似，然而其中的值不要求必须是唯一的（即可以有重复）。<br />multimap（多重映射）——和映射（map）相似，然而其中的键值不要求必须是唯一的（即可以有重复）。<br />注意：如果你阅读微软的帮助文档，你会遇到对每种容器的效率的陈述。比如：log(n*n)的插入时间。除非你要处理大量的数据，否则这些时间的影响是可以忽略的。如果你发现你的程序有明显的滞后感或者需要处理时间攸关（time critical）的事情，你可以去了解更多有关各种容器运行效率的话题。<br /><br />怎样在一个map中使用类？<br /><br />Map是一个通过key（键）来获得value(值)的模板类。<br />另一个<a class="Channel_KeyLink" href="http://www.qhtx.net/BBS">问题</a>是你希望在map中使用自己的类而不是已有的数据类型，比如现在已经用过的int。建立一个“为模板准备的（template-ready）”类，你必须确保在该类中包含一些成员函数和重载操作符。下面的一些成员是必须的：<br /><br />缺省的构造函数（通常为空）<br /><br />拷贝构造函数<br /><br />重载的”=”运算符<br /><br />你应该重载尽可能多的运算符来满足特定模板的需要，比如，如果你想定义一个类作为 map中的键（key），你必须重载相关的运算符。但在这里不对重载运算符做过多<a class="Channel_KeyLink" href="http://www.qhtx.net/BBS">讨论</a>了。<br /><br />//程序：映射自定义的类。<br />//目的：说明在map中怎样使用自定义的类。<br /><br />#include &lt;string&gt;<br />#include &lt;iostream&gt;<br />#include &lt;vector&gt;<br />#include &lt;map&gt;<br />using namespace std;<br /><br />class CStudent<br />{<br />public :<br /> int nStudentID;<br /> int nAge;<br />public :<br /> //缺省构造函数——通常为空<br /> CStudent() { }<br /> // 完整的构造函数<br /> CStudent(int nSID, int nA) { nStudentID=nSID; nAge=nA; }<br /> //拷贝构造函数<br /> CStudent(const CStudent&amp; ob) <br />  { nStudentID=ob.nStudentID; nAge=ob.nAge; }<br /> // 重载“=”<br /> void operator = (const CStudent&amp; ob) <br />  { nStudentID=ob.nStudentID; nAge=ob.nAge; }<br />};<br /><br />int main(int argc, char* argv[])<br />{<br /> map &lt;string, CStudent&gt; mapStudent;<br /><br /> mapStudent["Joe Lennon"] = CStudent(103547, 22);<br /> mapStudent["Phil McCartney"] = CStudent(100723, 22);<br /> mapStudent["Raoul Starr"] = CStudent(107350, 24);<br /> mapStudent["Gordon Hamilton"] = CStudent(102330, 22);<br /><br /> // 通过姓名来访问Cstudent类中的成员<br /> cout &lt;&lt; "The Student number for Joe Lennon is " &lt;&lt; <br />  (mapStudent["Joe Lennon"].nStudentID) &lt;&lt; endl;<br /><br /> return 0;<br />}<br /><br /><br /><br />TYPEDEF<br /><br />如果你喜欢使用typedef关键字，下面是个例子：<br />typedef set &lt;int&gt; SET_INT;<br />typedef SET_INT::iterator SET_INT_ITER<br /><br /><br />编写代码的一个习惯就是使用大写字母和下划线来命名数据类型。<br /><br />ANSI / ISO字符串<br /><br />ANSI/ISO字符串在STL容器中使用得很普遍。这是标准的字符串类，并得到了广泛地提倡，然而在缺乏格式声明的情况下就会出<a class="Channel_KeyLink" href="http://www.qhtx.net/BBS">问题</a>。你必须使用“&lt;&lt;”和输入输出流（iostream）代码（如dec, width等）将字符串串联起来。<br />可在必要的时候使用c_str()来重新获得字符指针。<br />游标（Iterator）<br /><br />我说过游标是指针，但不仅仅是指针。游标和指针很像，功能很像指针，但是实际上，游标是通过重载一元的”*”和”-&gt;”来从容器中间接地返回一个值。将这些值存储在容器中并不是一个好主意，因为每当一个新值添加到容器中或者有一个值从容器中删除，这些值就会失效。在某种程度上，游标可以看作是句柄（handle）。通常情况下游标（iterator）的类型可以有所变化，这样容器也会有几种不同方式的转变：<br />iterator——对于除了vector以外的其他任何容器，你可以通过这种游标在一次操作中在容器中朝向前的方向走一步。这意味着对于这种游标你只能使用“++”操作符。而不能使用“--”或“+=”操作符。而对于vector这一种容器，你可以使用“+=”、“—”、“++”、“-=”中的任何一种操作符和“&lt;”、“&lt;=”、“&gt;”、“&gt;=”、“==”、“!=”等比较运算符。<br />reverse_iterator ——如果你想用向后的方向而不是向前的方向的游标来遍历除vector之外的容器中的元素，你可以使用reverse_iterator 来反转遍历的方向，你还可以用rbegin()来代替begin()，用rend()代替end()，而此时的“++”操作符会朝向后的方向遍历。 <br />const_iterator ——一个向前方向的游标，它返回一个常数值。你可以使用这种类型的游标来指向一个只读的值。<br />const_reverse_iterator ——一个朝反方向遍历的游标，它返回一个常数值。<br /><br />Set和Map中的排序<br /><br />除了类型和值外，模板含有其他的参数。你可以传递一个回调函数（通常所说的声明“predicate”——这是带有一个参数的函数返回一个布尔值）。例如，如果你想自动建立一个集合，集合中的元素按升序排列，你可以用简明的方法建立一个set类：<br /><br />set &lt;int, greater&lt;int&gt; &gt; set1<br /><br />greater 是另一个模板函数（范型函数），当值放置在容器中后，它用来为这些值排序。如果你想按降序排列这些值，你可以这样写：<br /><br />set &lt;int, less&lt;int&gt; &gt; set1<br /><br />在实现算法时，将声明（predicate）作为一个参数传递到一个STL模板类中时会遇到很多的其他情况，下面将会对这些情况进行详细描述。<br /><br />STL 的烦恼之二——错误信息<br /><br />这些模板的命名需要对编译器进行扩充，所以当编译器因某种原因发生故障时，它会列出一段很长的错误信息，并且这些错误信息晦涩难懂。我觉得处理这样的难题没有什么好办法。但最好的方法是去查找并仔细研究错误信息指明代码段的尾端。还有一个烦恼就是：当你双击错误信息时，它会将错误指向模版库的内部代码，而这些代码就更难读了。一般情况下，纠错的最好方法是重新检查一下你的代码，运行时忽略所有的警告信息。<br /><br />算法（Algorithms）<br /><br />算法是模板中使用的函数。这才真正开始体现STL的强大之处。你可以学习一些大多数模板容器中都会用到的一些算法函数，这样你可以通过最简便的方式进行排序、查找、交换等操作。STL中包含着一系列实现算法的函数。比如：sort(vec.begin()+1, vec.end()-1)可以实现对除第一个和最后一个元素的其他元素的排序操作。<br />容器自身不能使用算法，但两个容器中的游标可以限定容器中使用算法的元素。既然这样，算法不直接受到容器的限制，而是通过采用游标，算法才能够得到支持。此外，很多次你会遇到传递一个已经准备好了的函数（以前提到的声明：predicate）作为参数，你也可以传递以前的旧值。<br />下面的例子演示了怎样使用算法：<br /><br />//程序：测试分数统计<br />//目的：通过对向量中保存的分数的操作说明怎样使用算法 <br /><br />#include &lt;algorithm&gt; //如果要使用算法函数，你必须要包含这个头文件。<br />#include &lt;numeric&gt; // 包含accumulate（求和）函数的头文件<br />#include &lt;vector&gt;<br />#include &lt;iostream&gt;<br />using namespace std;<br /><br />int testscore[] = {67, 56, 24, 78, 99, 87, 56};<br /><br />//判断一个成绩是否通过了考试<br />bool passed_test(int n)<br />{<br /> return (n &gt;= 60);<br />}<br /><br />// 判断一个成绩是否不及格<br />bool failed_test(int n)<br />{<br /> return (n &lt; 60);<br />}<br /><br />int main(int argc, char* argv[])<br />{<br /> int total;<br /> // 初始化向量，使之能够装入testscore数组中的元素<br /> vector &lt;int&gt; vecTestScore(testscore, <br />   testscore + sizeof(testscore) / sizeof(int));<br /> vector &lt;int&gt;::iterator vi;<br /><br /> // 排序并显示向量中的数据<br /> sort(vecTestScore.begin(), vecTestScore.end());<br /> cout &lt;&lt; "Sorted Test Scores:" &lt;&lt; endl;<br /> for (vi=vecTestScore.begin(); vi != vecTestScore.end(); vi++)<br /> { cout &lt;&lt; *vi &lt;&lt; ", "; }<br /> cout &lt;&lt; endl;<br /><br /> // 显示统计信息<br /><br /> // min_element 返回一个 _iterator_ 类型的对象，该对象指向值最小的那个元素。<br /> //“*”运算符提取元素中的值。<br /> vi = min_element(vecTestScore.begin(), vecTestScore.end());<br /> cout &lt;&lt; "The lowest score was " &lt;&lt; *vi &lt;&lt; "." &lt;&lt; endl;<br /><br /> //与min_element类似，max_element是选出最大值。<br /> vi = max_element(vecTestScore.begin(), vecTestScore.end());<br /> cout &lt;&lt; "The highest score was " &lt;&lt; *vi &lt;&lt; "." &lt;&lt; endl;<br /><br /> // 使用声明函数（predicate function，指vecTestScore.begin()和vecTestScore.end()）来确定通过考试的人数。<br /> cout &lt;&lt; count_if(vecTestScore.begin(), vecTestScore.end(), passed_test) &lt;&lt; <br />  " out of " &lt;&lt; vecTestScore.size() &lt;&lt; <br />  " students passed the test" &lt;&lt; endl;<br /><br /> // 确定有多少人考试挂了<br /> cout &lt;&lt; count_if(vecTestScore.begin(), <br />  vecTestScore.end(), failed_test) &lt;&lt; <br />  " out of " &lt;&lt; vecTestScore.size() &lt;&lt; <br />  " students failed the test" &lt;&lt; endl;<br /><br /> //计算成绩总和<br /> total = accumulate(vecTestScore.begin(), <br />   vecTestScore.end(), 0);<br /> // 计算显示平均成绩<br /> cout &lt;&lt; "Average score was " &lt;&lt; <br />  (total / (int)(vecTestScore.size())) &lt;&lt; endl;<br /><br /> return 0;<br />}<br /><br /><br />Allocator（分配器）<br /><br />Allocator用在模板的初始化阶段，是为对象和数组进行分配内存空间和释放空间操作的模板类。它在各种情况下扮演着很神秘的角色，它关心的是高层内存的优化，而且对黑盒测试来说，使用Allocator是最好的选择。通常，我们不需要明确指明它，因为它们通常是作为不用添加的缺省的参数出现的。如果在专业的测试工作中出现了Allocator，你最好搞清楚它是什么。<br /><br />Embed Templates（嵌入式模版）和Derive Templates（基模板）<br /><br />每当你使用一个普通的类的时候，你也可以在其中使用一个STL类。它是可以被嵌入的：<br /><br />class CParam<br />{<br /> string name;<br /> string unit;<br /> vector &lt;double&gt; vecData;<br />};<br /><br /><br />或者将它作为一个基类：<br /><br />class CParam : public vector &lt;double&gt;<br />{<br /> string name;<br /> string unit;<br />};<br /><br /><br />STL模版类作为基类时需要谨慎。这需要你适应这种编程方式。<br /><br />模版中的模版<br /><br />为构建一个复杂的数据结构，你可以将一个模板植入另一个模板中（即“模版嵌套”）。一般最好的方法是在程序前面使用typedef关键字来定义一个在另一个模板中使用的模版类型。<br /><br />// 程序：在向量中嵌入向量的演示。<br />//目的：说明怎样使用嵌套的STL容器。<br /><br />#include &lt;iostream&gt;<br />#include &lt;vector&gt;<br /><br />using namespace std;<br /><br />typedef vector &lt;int&gt; VEC_INT;<br /><br />int inp[2][2] = {{1, 1}, {2, 0}}; <br /> // 要放入模板中的2x2的正则数组<br /><br />int main(int argc, char* argv[])<br />{<br /> int i, j;<br /> vector &lt;VEC_INT&gt; vecvec;<br /> // 如果你想用一句话实现这样的嵌套，你可以这样写：<br /> // vector &lt;vector &lt;int&gt; &gt; vecvec;<br /> <br /> // 将数组填入向量<br /> VEC_INT v0(inp[0], inp[0]+2); <br />  // 传递两个指针<br />  // 将数组中的值拷贝到向量中<br /> VEC_INT v1(inp[1], inp[1]+2);<br /><br /> vecvec.push_back(v0);<br /> vecvec.push_back(v1);<br /><br /> for (i=0; i&lt;2; i++)<br /> {<br />  for (j=0; j&lt;2; j++)<br />  {<br />   cout &lt;&lt; vecvec[i][j] &lt;&lt; " ";<br />  }<br />  cout &lt;&lt; endl;<br /> }<br /> return 0;<br />}<br /><br />// 输出：<br />// 1 1<br />// 2 0<br /><br /><br />虽然在初始化时很麻烦，一旦你将数据填如向量中，你就实现了一个变长的可扩充的二维数组（大小可扩充直到使用完内存）。根据实际需要，可以使用各种容器的嵌套组合。<br /><br />总结<br /><br />STL是有用的，但是使用过程中的困难和麻烦是再所难免的。就像中国人所说的：“如果你掌握了它，便犹如虎添翼。”<br /><a class="listA" title="教程标题：STL实践指南Practical Guide to STL（上）&#xD;&#xA;作    者：Jeff Bogan&#xD;&#xA;更新时间：2006-1-15 19:13:19" href="http://zcy.wefine.com/edu/program/vc/vc8/200601/10899.html" target="_blank"></a></p>
<img src ="http://www.cppblog.com/Lori/aggbug/17028.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Lori/" target="_blank">张岁滔</a> 2006-12-30 12:32 <a href="http://www.cppblog.com/Lori/articles/17028.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>pragma指令简介(转贴) </title><link>http://www.cppblog.com/Lori/articles/17027.html</link><dc:creator>张岁滔</dc:creator><author>张岁滔</author><pubDate>Sat, 30 Dec 2006 04:29:00 GMT</pubDate><guid>http://www.cppblog.com/Lori/articles/17027.html</guid><wfw:comment>http://www.cppblog.com/Lori/comments/17027.html</wfw:comment><comments>http://www.cppblog.com/Lori/articles/17027.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Lori/comments/commentRss/17027.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Lori/services/trackbacks/17027.html</trackback:ping><description><![CDATA[
		<div class="postbody">在编写程序的时候<b><font color="#663300">,</font></b>我们经常要用到#pragma指令来设定编译器的状态或者是指示编译器完成一些特定的动作<b><font color="#663300">.</font></b><br />下面介绍了一下该指令的一些常用参数<b><font color="#663300">,</font></b>希望对大家有所帮助<b><font color="#663300">!</font></b><br /><br />一<b><font color="#663300">.</font></b> message 参数。<br />message<br />它能够在编译信息输出窗<br />口中输出相应的信息，这对于源代码信息的控制是非常重要的。<br /><br />其使用方法为：    #pragma message<b><font color="#663300">(</font></b><font color="#009900">"消息文本"</font><b><font color="#663300">)</font></b><br /><br />当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。<br />当我们在程序中定义了许多宏来控制源代码版本的时候，我们自己有可能都会忘记有没有正确的设置这些宏，此时我们可以用这条指令在编译的时候就进行检查。假设我们希望判断自己有没有在源代码的什么地方定义了_X86这个宏可以用下面的方法：<font color="#000099"><br />#ifdef _X86<br />#pragma message("_X86 macro activated!")<br />#endif<br /></font>当我们定义了_X86这个宏以后，应用程序在编译时就会在编译输出窗口里显示<font color="#009900"><br />"_X86 macro activated!"</font><br />这样，我们就不会因为不记得自己定义的一些特定的宏而抓耳挠腮了。<br /><br />二<b><font color="#663300">.</font></b> 另一个使用得比较多的#pragma参数是code_seg。<br />格式如：<font color="#000099"><br /><br />#pragma code_seg( [ [ { push | pop}, ] [ identifier, ] ] [ "segment-name" [, "segment-class" ] )<br /></font>该指令用来指定函数在<b><font color="#663300">.</font></b>obj文件中存放的节<b><font color="#663300">,</font></b>观察OBJ文件可以使用VC自带的dumpbin命令行程序<b><font color="#663300">,</font></b>函数在<b><font color="#663300">.</font></b>obj文件中默认的存放节为<b><font color="#663300">.</font></b>text节，如果code_seg没有带参数的话<b><font color="#663300">,</font></b>则函数存放在<b><font color="#663300">.</font></b>text节中。<br /><br />push<b><font color="#663300"> (</font></b>可选参数<b><font color="#663300">)</font></b> 将一个记录放到内部编译器的堆栈中<b><font color="#663300">,</font></b>可选参数可以为一个标识符或者节名<br />pop<b><font color="#663300">(</font></b>可选参数<b><font color="#663300">)</font></b> 将一个记录从堆栈顶端弹出<b><font color="#663300">,</font></b>该记录可以为一个标识符或者节名<br />identifier<b><font color="#663300"> (</font></b>可选参数<b><font color="#663300">)</font></b> 当使用push指令时<b><font color="#663300">,</font></b>为压入堆栈的记录指派的一个标识符<b><font color="#663300">,</font></b>当该标识符被删除的时候和其相关的堆栈中的记录将被弹出堆栈<font color="#009900"><br />"segment-name"</font><b><font color="#663300"> (</font></b>可选参数<b><font color="#663300">)</font></b> 表示函数存放的节名<br />例如<b><font color="#663300">:</font></b><i><font color="#999999"><br />//默认情况下,函数被存放在.text节中<br /></font></i><font color="#ff6633">void</font> func1<b><font color="#663300">() {</font></b><i><font color="#999999">                  // stored in .text<br /></font></i><b><font color="#663300">}</font></b><i><font color="#999999"><br /><br />//将函数存放在.my_data1节中<br /></font></i><font color="#000099">#pragma code_seg(".my_data1")<br /></font><font color="#ff6633">void</font> func2<b><font color="#663300">() {</font></b><i><font color="#999999">                  // stored in my_data1<br /></font></i><b><font color="#663300">}</font></b><i><font color="#999999"><br /><br />//r1为标识符,将函数放入.my_data2节中<br /></font></i><font color="#000099">#pragma code_seg(push, r1, ".my_data2")<br /></font><font color="#ff6633">void</font> func3<b><font color="#663300">() {</font></b><i><font color="#999999">                  // stored in my_data2<br /></font></i><b><font color="#663300">}</font></b><font color="#ff6633"><br /><br />int</font><font color="#990000"> main</font><b><font color="#663300">() {<br />}</font></b><br /><br />三<b><font color="#663300">.</font></b> #pragma once<b><font color="#663300"> (</font></b>比较常用）<br />这是一个比较常用的指令<b><font color="#663300">,</font></b>只要在头文件的最开始加入这条指令就能够保证头文件被编译一次<br /><br />四<b><font color="#663300">.</font></b> #pragma hdrstop表示预编译头文件到此为止，后面的头文件不进行预编译。<br />BCB可以预编译头文件以加快链接的速度，但如果所有头文件都进行预编译又可能占太多磁盘空间，所以使用这个选项排除一些头文件。<br />有时单元之间有依赖关系，比如单元A依赖单元B，所以单元B要先于单元A编译。你可以用#pragma startup指定编译优先级，如果使用了#pragma package<b><font color="#663300">(</font></b>smart_init<b><font color="#663300">)</font></b> ，BCB就会根据优先级的大小先后编译。<br /><br />五<b><font color="#663300">.</font></b> #pragma warning指令<br />该指令允许有选择性的修改编译器的警告消息的行为<br />指令格式如下<b><font color="#663300">:</font></b><font color="#000099"><br />#pragma warning( warning-specifier : warning-number-list [; warning-specifier : warning-number-list...]<br />#pragma warning( push[ ,n ] )<br />#pragma warning( pop )<br /></font><br />主要用到的警告表示有如下几个<b><font color="#663300">:</font></b><br /><br />once<b><font color="#663300">:</font></b>只显示一次<b><font color="#663300">(</font></b>警告<b><font color="#663300">/</font></b>错误等<b><font color="#663300">)</font></b>消息<font color="#ff0000"><br />default</font><b><font color="#663300">:</font></b>重置编译器的警告行为到默认状态<font color="#999900"><br />1</font><b><font color="#663300">,</font></b><font color="#999900">2</font><b><font color="#663300">,</font></b><font color="#999900">3</font><b><font color="#663300">,</font></b><font color="#999900">4</font><b><font color="#663300">:</font></b>四个警告级别<br />disable<b><font color="#663300">:</font></b>禁止指定的警告信息<br />error<b><font color="#663300">:</font></b>将指定的警告信息作为错误报告<br /><br />如果大家对上面的解释不是很理解<b><font color="#663300">,</font></b>可以参考一下下面的例子及说明<font color="#000099"><br /><br />#pragma warning( disable : 4507 34; once : 4385; error : 164 )<br /></font>等价于：<font color="#000099"><br />#pragma warning(disable:4507 34)  // 不显示4507和34号警告信息<br />#pragma warning(once:4385)        // 4385号警告信息仅报告一次<br />#pragma warning(error:164)        // 把164号警告信息作为一个错误。<br /></font>同时这个pragma warning 也支持如下格式：<font color="#000099"><br />#pragma warning( push [ ,n ] )<br />#pragma warning( pop )<br /></font>这里n代表一个警告等级<b><font color="#663300">(</font></b><font color="#999900">1</font><b><font color="#663300">---</font></b><font color="#999900">4</font><b><font color="#663300">)</font></b>。<font color="#000099"><br />#pragma warning( push )保存所有警告信息的现有的警告状态。<br />#pragma warning( push, n)保存所有警告信息的现有的警告状态，并且把全局警告等级设定为n。<br />#pragma warning( pop )向栈中弹出最后一个警告信息，在入栈和出栈之间所作的一切改动取消。例如：<br />#pragma warning( push )<br />#pragma warning( disable : 4705 )<br />#pragma warning( disable : 4706 )<br />#pragma warning( disable : 4707 )<br />#pragma warning( pop )<br /></font><br />在这段代码的最后，重新保存所有的警告信息<b><font color="#663300">(</font></b>包括<font color="#999900">4705</font>，<font color="#999900">4706</font>和<font color="#999900">4707</font><b><font color="#663300">)</font></b><br /><br />在使用标准C<b><font color="#663300">++</font></b>进行编程的时候经常会得到很多的警告信息<b><font color="#663300">,</font></b>而这些警告信息都是不必要的提示<b><font color="#663300">,</font></b>所以我们可以使用#pragma warning<b><font color="#663300">(</font></b>disable<b><font color="#663300">:</font></b><font color="#999900">4786</font><b><font color="#663300">)</font></b>来禁止该类型的警告在vc中使用ADO的时候也会得到不必要的警告信息<b><font color="#663300">,</font></b>这个时候我们可以通过#pragma warning<b><font color="#663300">(</font></b>disable<b><font color="#663300">:</font></b><font color="#999900">4146</font><b><font color="#663300">)</font></b>来消除该类型的警告信息<br /><br />六<b><font color="#663300">.</font></b> pragma comment<b><font color="#663300">(...)</font></b><br />该指令的格式为：  #pragma comment<b><font color="#663300">(</font></b><font color="#009900"> "comment-type"</font><b><font color="#663300"> [,</font></b> commentstring<b><font color="#663300">] )</font></b><br />该指令将一个注释记录放入一个对象文件或可执行文件中<b><font color="#663300">,</font></b>comment<b><font color="#663300">-</font></b>type<b><font color="#663300">(</font></b>注释类型<b><font color="#663300">):</font></b>可以指定为五种预定义的标识符的其中一种。<br />五种预定义的标识符为<b><font color="#663300">:</font></b><font color="#999900"><br /><br />1</font>、compiler<b><font color="#663300">:</font></b>将编译器的版本号和名称放入目标文件中<b><font color="#663300">,</font></b>本条注释记录将被编译器忽略<br />如果你为该记录类型提供了commentstring参数<b><font color="#663300">,</font></b>编译器将会产生一个警告<br />例如<b><font color="#663300">:</font></b>#pragma comment<b><font color="#663300">(</font></b> compiler<b><font color="#663300"> )</font></b><font color="#999900"><br /><br />2</font>、exestr<b><font color="#663300">:</font></b>将commentstring参数放入目标文件中<b><font color="#663300">,</font></b>在链接的时候这个字符串将被放入到可执行文件中<b><font color="#663300">,</font></b>当操作系统加载可执行文件的时候<b><font color="#663300">,</font></b>该参数字符串不会被加载到内存中<b><font color="#663300">.</font></b>但是<b><font color="#663300">,</font></b>该字符串可以被dumpbin之类的程序查找出并打印出来<b><font color="#663300">,</font></b>你可以用这个标识符将版本号码之类的信息嵌入到可执行文件中<b><font color="#663300">!</font></b><font color="#999900"><br /><br />3</font>、lib<b><font color="#663300">:</font></b>这是一个非常常用的关键字<b><font color="#663300">,</font></b>用来将一个库文件链接到目标文件中常用的lib关键字，可以帮我们连入一个库文件。<br />例如<b><font color="#663300">:</font></b><font color="#000099"> <br />#pragma comment(lib, "user32.lib")<br /></font>该指令用来将user32<b><font color="#663300">.</font></b>lib库文件加入到本工程中<font color="#999900"><br /><br />4</font>、linker<b><font color="#663300">:</font></b>将一个链接选项放入目标文件中<b><font color="#663300">,</font></b>你可以使用这个指令来代替由命令行传入的或者在开发环境中设置的链接选项<b><font color="#663300">,</font></b>你可以指定<b><font color="#663300">/</font></b>include选项来强制包含某个对象<b><font color="#663300">,</font></b>例如<b><font color="#663300">:</font></b><font color="#000099"><br />#pragma comment(linker, "/include:__mySymbol")<br /></font>你可以在程序中设置下列链接选项<b><font color="#663300"><br />/</font></b>DEFAULTLIB<b><font color="#663300"><br />/</font></b>EXPORT<b><font color="#663300"><br />/</font></b>INCLUDE<b><font color="#663300"><br />/</font></b>MERGE<b><font color="#663300"><br />/</font></b>SECTION<br /><br />这些选项在这里就不一一说明了<b><font color="#663300">,</font></b>详细信息请看msdn<b><font color="#663300">!</font></b><font color="#999900"><br /><br />5</font>、user<b><font color="#663300">:</font></b>将一般的注释信息放入目标文件中commentstring参数包含注释的文本信息<b><font color="#663300">,</font></b>这个注释记录将被链接器忽略<br />例如<b><font color="#663300">:</font></b><font color="#000099"><br />#pragma comment( user, "Compiled on " __DATE__ " at " __TIME__ )</font></div>
<img src ="http://www.cppblog.com/Lori/aggbug/17027.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Lori/" target="_blank">张岁滔</a> 2006-12-30 12:29 <a href="http://www.cppblog.com/Lori/articles/17027.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>