﻿<?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++博客-persistence-随笔分类-Language</title><link>http://www.cppblog.com/liangbo/category/1183.html</link><description>Software Architecture</description><language>zh-cn</language><lastBuildDate>Mon, 19 May 2008 16:16:39 GMT</lastBuildDate><pubDate>Mon, 19 May 2008 16:16:39 GMT</pubDate><ttl>60</ttl><item><title>泛型程序设计是C++的发展方向或者是出路吗？</title><link>http://www.cppblog.com/liangbo/archive/2007/05/04/23400.html</link><dc:creator>bo</dc:creator><author>bo</author><pubDate>Fri, 04 May 2007 06:03:00 GMT</pubDate><guid>http://www.cppblog.com/liangbo/archive/2007/05/04/23400.html</guid><wfw:comment>http://www.cppblog.com/liangbo/comments/23400.html</wfw:comment><comments>http://www.cppblog.com/liangbo/archive/2007/05/04/23400.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/liangbo/comments/commentRss/23400.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/liangbo/services/trackbacks/23400.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
最近看了《C++设计新思维》一书的前几章，总的感觉是不怎么爽。比起以前看《泛型编程 and STL》，boost库起来，感觉该书描述的东西太过于注重模板的技巧，C++是一个编译型的语言，一些动态语言很容易实现的功能C++实现起来就很难，我们完全没有必要硬是用大量的模板来强迫C++在编译期实现这些动态特性。语言只要是好用就行，而现在C++代码里几乎全是模板，并且越来越复杂，不知道以后谁还愿意这样写C++？难道泛型编程就是C++的发展方向吗？
<img src ="http://www.cppblog.com/liangbo/aggbug/23400.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/liangbo/" target="_blank">bo</a> 2007-05-04 14:03 <a href="http://www.cppblog.com/liangbo/archive/2007/05/04/23400.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转载:Sizeof与Strlen的区别与联系</title><link>http://www.cppblog.com/liangbo/archive/2006/10/06/13394.html</link><dc:creator>bo</dc:creator><author>bo</author><pubDate>Fri, 06 Oct 2006 02:40:00 GMT</pubDate><guid>http://www.cppblog.com/liangbo/archive/2006/10/06/13394.html</guid><wfw:comment>http://www.cppblog.com/liangbo/comments/13394.html</wfw:comment><comments>http://www.cppblog.com/liangbo/archive/2006/10/06/13394.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/liangbo/comments/commentRss/13394.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/liangbo/services/trackbacks/13394.html</trackback:ping><description><![CDATA[
		<p>
		</p>
		<p>
				<strong>
				</strong>
		</p>strlen与sizeof的区别<br /><br />1.sizeof操作符的结果类型是size_t，它在头文件中typedef为unsigned　int类型。<br />该类型保证能容纳实现所建立的最大对象的字节大小。 
<p></p><p>2.sizeof是算符，strlen是函数。 </p><p>3.sizeof可以用类型做参数，strlen只能用char*做参数，且必须是以''\0''结尾的。</p><p>4.数组做sizeof的参数不退化，传递给strlen就退化为指针了。 </p><p>5.大部分编译程序在编译的时候就把sizeof计算过了 是类型或是变量的长度这就是sizeof(x)可以用来定义数组维数的原因 <br /><strong><font color="#3300cc">char str[20]="0123456789";//str是编译期大小已经固定的数组<br />int a=strlen(str); //a=10;//strlen()在运行起确定<br />int b=sizeof(str); //而b=20;//sizeof()在编译期确定</font></strong></p><p>6.strlen的结果要在运行的时候才能计算出来，是用来计算字符串的实际长度，不是类型占内存的大小。 </p><p>7.sizeof后如果是类型必须加括弧，如果是变量名可以不加括弧。这是因为sizeof是个操作符不是个函数。<br /> <font color="#0000ff"><strong>char c;<br /></strong></font><font color="#0000ff"><strong> sizeof c;//变量名可以不加括弧</strong><br /></font> <br />8.当适用了于一个结构类型时或变量， sizeof 返回实际的大小，<br /> 当适用一静态地空间数组， sizeof 归还全部数组的尺寸。<br /> sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸 </p><p>9.数组作为参数传给函数时传的是指针而不是数组，传递的是数组的首地址，<br />如： <br />fun(char [8])<br />fun(char [])<br />都等价于 fun(char *) <br />在C++里参数传递数组永远都是传递指向数组首元素的指针，编译器不知道数组的大小<br />如果想在函数内知道数组的大小， 需要这样做：<br />进入函数后用memcpy拷贝出来，长度由另一个形参传进去 <br />fun(unsiged char *p1, int len)<br />{<br />  unsigned char* buf = new unsigned char[len+1]<br />  memcpy(buf, p1, len);<br />}</p><p>我们能常在用到 sizeof 和 strlen 的时候，通常是计算字符串数组的长度<br />看了上面的详细解释，发现两者的使用还是有区别的，从这个例子可以看得很清楚：</p><p>har str[11]="0123456789";//注意这里str大小因该大于等于11，应考虑'\0'在内，否则编译器会报错<br />int a=strlen(str); //a=10; &gt;&gt;&gt;&gt; strlen 计算字符串的长度，以结束符 0x00 为字符串结束。<br />int b=sizeof(str); //而b=11; &gt;&gt;&gt;&gt; sizeof 计算的则是分配的数组 str[11] 所占的内存空间的大小，不受里面存储的内容改变。  </p><p>上面是对静态数组处理的结果，如果是对指针，结果就不一样了</p><p>char* ss = "0123456789";<br />sizeof(ss) 结果 4 ＝＝＝》ss是指向字符串常量的字符指针，sizeof 获得的是一个指针的之所占的空间,应该是长整型的，所以是4<br />sizeof(*ss) 结果 1 ＝＝＝》*ss是第一个字符 其实就是获得了字符串的第一位'0' 所占的内存空间，是char类型的，占了 1 位strlen(ss)= 10 &gt;&gt;&gt;&gt; 如果要获得这个字符串的长度，则一定要使用 strlen<br /><br />另外,下面的方法可以用于确定该静态数组可以容纳元素的个数：<br />int a[3]={1,2,3};<br />cout &lt;&lt; sizeof a/sizeof ( typeid( a[0] ).name() );</p><img src ="http://www.cppblog.com/liangbo/aggbug/13394.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/liangbo/" target="_blank">bo</a> 2006-10-06 10:40 <a href="http://www.cppblog.com/liangbo/archive/2006/10/06/13394.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows环境下Unicode编程总结 (转载自CSDN  )</title><link>http://www.cppblog.com/liangbo/archive/2006/04/23/6103.html</link><dc:creator>bo</dc:creator><author>bo</author><pubDate>Sun, 23 Apr 2006 10:21:00 GMT</pubDate><guid>http://www.cppblog.com/liangbo/archive/2006/04/23/6103.html</guid><wfw:comment>http://www.cppblog.com/liangbo/comments/6103.html</wfw:comment><comments>http://www.cppblog.com/liangbo/archive/2006/04/23/6103.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/liangbo/comments/commentRss/6103.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/liangbo/services/trackbacks/6103.html</trackback:ping><description><![CDATA[
		<p>UNICODE环境设置<br />在安装Visual Studio时，在选择VC++时需要加入unicode选项，保证相关的库文件可以拷贝到system32下。</p>
		<p>
				<br />UNICODE编译设置：<br />C/C++, Preprocessor difinitions 去除_MBCS，加_UNICODE,UNICODE<br />在ProjectSetting/link/output 中设置Entry为wWinMainCRTStartup<br />反之为MBCS（ANSI）编译。</p>
		<p>
				<br />Unicode ：宽字节字符集</p>
		<p>
				<br />1. 如何取得一个既包含单字节字符又包含双字节字符的字符串的字符个数？<br />可以调用Microsoft Visual C++的运行期库包含函数_mbslen来操作多字节（既包括单字节也包括双字节）字符串。<br />调用strlen函数，无法真正了解字符串中究竟有多少字符，它只能告诉你到达结尾的0之前有多少个字节。</p>
		<p>
				<br />2. 如何对DBCS（双字节字符集）字符串进行操作？<br />函数 描述<br />PTSTR CharNext （ LPCTSTR ）; 返回字符串中下一个字符的地址<br />PTSTR CharPrev （ LPCTSTR, LPCTSTR ）； 返回字符串中上一个字符的地址<br />BOOL IsDBCSLeadByte( BYTE )； 如果该字节是DBCS字符的第一个字节，则返回非0值</p>
		<p>
				<br />3. 为什幺要使用Unicode？<br />（1） 可以很容易地在不同语言之间进行数据交换。<br />（2） 使你能够分配支持所有语言的单个二进制.exe文件或DLL文件。<br />（3） 提高应用程序的运行效率。<br />Windows 2000是使用Unicode从头进行开发的，如果调用任何一个Windows函数并给它传递一个ANSI字符串，那幺系统首先要将字符串转换成Unicode，然后将Unicode字符串传递给操作系统。如果希望函数返回ANSI字符串，系统就会首先将Unicode字符串转换成ANSI字符串，然后将结果返回给你的应用程序。进行这些字符串的转换需要占用系统的时间和内存。通过从头开始用Unicode来开发应用程序，就能够使你的应用程序更加有效地运行。<br />Windows CE 本身就是使用Unicode的一种操作系统，完全不支持ANSI Windows函数<br />Windows 98 只支持ANSI，只能为ANSI开发应用程序。<br />Microsoft公司将COM从16位Windows转换成Win32时，公司决定需要字符串的所有COM接口方法都只能接受Unicode字符串。</p>
		<p>
				<br />4. 如何编写Unicode源代码？<br />Microsoft公司为Unicode设计了WindowsAPI，这样，可以尽量减少代码的影响。实际上，可以编写单个源代码文件，以便使用或者不使用Unicode来对它进行编译。只需要定义两个宏（UNICODE和_UNICODE），就可以修改然后重新编译该源文件。<br />_UNICODE宏用于C运行期头文件，而UNICODE宏则用于Windows头文件。当编译源代码模块时，通常必须同时定义这两个宏。</p>
		<p>
				<br />5. Windows定义的Unicode数据类型有哪些？<br />数据类型 说明<br />WCHAR Unicode字符<br />PWSTR 指向Unicode字符串的指针<br />PCWSTR 指向一个恒定的Unicode字符串的指针<br />对应的ANSI数据类型为CHAR，LPSTR和LPCSTR。<br />ANSI/Unicode通用数据类型为TCHAR，PTSTR,LPCTSTR。</p>
		<p>
				<br />6. 如何对Unicode进行操作？<br />字符集 特性 实例<br />ANSI 操作函数以str开头 strcpy<br />Unicode 操作函数以wcs开头 wcscpy<br />MBCS 操作函数以_mbs开头 _mbscpy<br />ANSI/Unicode 操作函数以_tcs开头 _tcscpy（C运行期库）<br />ANSI/Unicode 操作函数以lstr开头 lstrcpy（Windows函数）<br />所有新的和未过时的函数在Windows2000中都同时拥有ANSI和Unicode两个版本。ANSI版本函数结尾以A表示；Unicode版本函数结尾以W表示。Windows会如下定义：<br />#ifdef UNICODE<br />#define CreateWindowEx CreateWindowExW<br />#else<br />#define CreateWindowEx CreateWindowExA<br />#endif // !UNICODE</p>
		<p>
				<br />7. 如何表示Unicode字符串常量？<br />字符集 实例<br />ANSI “string”<br />Unicode L“string”<br />ANSI/Unicode T(“string”)或_TEXT(“string”)if( szError[0] == _TEXT(‘J’) ){ }</p>
		<p>
				<br />8. 为什幺应当尽量使用操作系统函数？<br />这将有助于稍稍提高应用程序的运行性能，因为操作系统字符串函数常常被大型应用程序比如操作系统的外壳进程Explorer.exe所使用。由于这些函数使用得很多，因此，在应用程序运行时，它们可能已经被装入RAM。<br />如：StrCat，StrChr，StrCmp和StrCpy等。</p>
		<p>
				<br />9. 如何编写符合ANSI和Unicode的应用程序？<br />（1） 将文本串视为字符数组，而不是chars数组或字节数组。<br />（2） 将通用数据类型（如TCHAR和PTSTR）用于文本字符和字符串。<br />（3） 将显式数据类型（如BYTE和PBYTE）用于字节、字节指针和数据缓存。<br />（4） 将TEXT宏用于原义字符和字符串。<br />（5） 执行全局性替换（例如用PTSTR替换PSTR）。<br />（6） 修改字符串运算问题。例如函数通常希望在字符中传递一个缓存的大小，而不是字节。这意味着不应该传递sizeof(szBuffer),而应该传递（sizeof(szBuffer)/sizeof(TCHAR)。另外，如果需要为字符串分配一个内存块，并且拥有该字符串中的字符数目，那幺请记住要按字节来分配内存。这就是说，应该调用<br />malloc(nCharacters *sizeof(TCHAR)),而不是调用malloc(nCharacters)。</p>
		<p>
				<br />10. 如何对字符串进行有选择的比较？<br />通过调用CompareString来实现。<br />标志 含义<br />NORM_IGNORECASE 忽略字母的大小写<br />NORM_IGNOREKANATYPE 不区分平假名与片假名字符<br />NORM_IGNORENONSPACE 忽略无间隔字符<br />NORM_IGNORESYMBOLS 忽略符号<br />NORM_IGNOREWIDTH 不区分单字节字符与作为双字节字符的同一个字符<br />SORT_STRINGSORT 将标点符号作为普通符号来处理</p>
		<p>
				<br />11. 如何判断一个文本文件是ANSI还是Unicode？<br />判断如果文本文件的开头两个字节是0xFF和0xFE，那幺就是Unicode，否则是ANSI。</p>
		<p>
				<br />12. 如何判断一段字符串是ANSI还是Unicode？<br />用IsTextUnicode进行判断。IsTextUnicode使用一系列统计方法和定性方法，以便猜测缓存的内容。由于这不是一种确切的科学方法，因此 IsTextUnicode有可能返回不正确的结果。</p>
		<p>
				<br />13. 如何在Unicode与ANSI之间转换字符串？<br />Windows函数MultiByteToWideChar用于将多字节字符串转换成宽字符串；函数WideCharToMultiByte将宽字符串转换成等价的多字节字符串。</p>
		<p>
				<br />14. Unicode和DBCS之间的区别<br />Unicode使用（特别在C程序设计语言环境里）“宽字符集”。「Unicode中的每个字符都是16位宽而不是8位宽。」在Unicode中，没有单单使用8位数值的意义存在。相比之下，在“双位组字符集”中我们仍然处理8位数值。有些位组自身定义字符，而某些位组则显示需要和另一个位组共同定义一个字符。<br />处理DBCS字符串非常杂乱，但是处理Unicode文字则像处理有秩序的文字。您也许会高兴地知道前128个Unicode字符（16位代码从0x0000到0x007F）就是ASCII字符，而接下来的128个Unicode字符（代码从0x0080到0x00FF）是ISO 8859-1对ASCII的扩展。Unicode中不同部分的字符都同样基于现有的标准。这是为了便于转换。希腊字母表使用从0x0370到0x03FF的代码，斯拉夫语使用从0x0400到0x04FF的代码，美国使用从0x0530到0x058F的代码，希伯来语使用从0x0590到0x05FF的代码。中国、日本和韩国的象形文字（总称为CJK）占用了从0x3000到0x9FFF的代码。Unicode的最大好处是这里只有一个字符集，没有一点含糊。</p>
		<p>
				<br />15.衍生标准<br />Unicode是一个标准。UTF-8是其概念上的子集，UTF-8是具体的编码标准。而ＵＮＩＣＯＤＥ是所有想达到世界统一编码标准的标准。UTF-8标准就是Unicode（ISO10646）标准的一种变形方式， <br />UTF的全称是：Unicode/UCS Transformation Format，其实有两种UTF，一种是UTF-8，一种是UTF-16， <br />不过UTF-16使用较少，其对应关系如下：<br />在Unicode中编码为 0000 - 007F 的 UTF-8 中编码形式为: 0xxxxxxx <br />在Unicode中编码为 0080 - 07FF 的 UTF-8 中编码形式为: 110xxxxx 10xxxxxx<br />在Unicode中编码为 0000 - 007F 的 UTF-8 中编码形式为: 1110xxxx 10xxxxxx 10xxxxxx</p>
		<p>
				<br />utf-8是unicode的一个新的编码标准,其实unicode有过好几个标准.我们知道一直以来使用的unicode字符内码都是16位,它实际上还不能把全世界的所有字符编在一个平面系统,比如中国的藏文等小语种,所以utf-8扩展到了32位,也就是说理论在utf-8中可容纳二的三十二次方个字符. UNICODE的思想就是想把所有的字符统一编码,实现一个统一的标准.big5、gb都是独立的字符集,这也叫做远东字符集,把它拿到德文版的WINDOWS上可能将会引起字符编码的冲突....早期的WINDOWS默认的字符集是ANSI.notepad中输入的汉字是本地编码,但在NT/2000内部是可以直接支持UNICODE的。notepad.exe在WIN95和98中都是ANSI字符,在NT中则是UNICODE.ANSI和UNICODE可以方便的实现对应映射,也就是转换 ASCII是8位范围内的字符集，对于范围之外的字符如汉字它是无法表达的。unicode是16位范围内的字符集，对于不同地区的字符分区分配，unicode是多个IT巨头共同制定的字符编码标准。如果在unicode环境下比如WINDOWS NT上，一个字符占两字节16位，而在ANSI环境下如WINDOWS98下一个字符占一个字节8位.Unicode字符是16位宽，最多允许65,535字符，数据类型被称为WCHAR。 <br />对于已有的ANSI字符，unicode简单的将其扩展为16位：比如ANSI"A"=0x43,则对应的UNICODE为<br />"A"= 0x0043<br />而ASCII用七存放128个字符,ASCII是一个真正的美国标准,所以它不能满足其他国家的需要,例如斯拉夫语的字母和汉字于是出现了Windows ANSI字符集,是一种扩展的ASCII码,用8位存放字符,低128位仍然存放原来的ASCII码, <br />而高128位加入了希腊字母等<br />if def UNICODE<br />  TCHAR = wchar<br />else<br />  TCHAR = char<br />你需要在Project\Settings\C/C++\Preprocesser definitions中添加UNICODE和_UNICODE <br />UINCODE,_UNICODE都要定义。不定义_UNICODE的话，用SetText(HWND,LPCTSTR),将被解释为SetTextA(HWND,LPTSTR),这时API将把你给的Unicode字符串看作ANSI字符串，显示乱码。因为windows API是已经编译好存在于dll中的，由于不管UNICODE还是ANSI字符串，都被看作一段buffer,如"0B A3 00 35 24 3C 00 00"如果按ANSI读，因为ANSI字串是以'\0'结束的，所以只能读到两字节"0B A3 \0"，如果按UNICODE读，将完整的读到'\0\0'结束。<br />由于UNICODE没有额外的指示位，所以系统必须知道你提供的字串是哪种格式。此外，UNICODE好象是ANSI C++规定的，_UNICODE是windows SDK提供的。如果不编写windows程序，可以只定义UNICODE。<br />开发过程：<br />围绕着文件读写、字符串处理展开。文件主要有两种：.txt和.ini文件<br />1.    在unicode和非unicode环境下字符串做不同处理的，那么需要参考以上9，10两条，以适应不同环境得字符串处理要求。<br />对文件读写也一样。只要调用相关接口函数时，参数中的字符串前都加上_TEXT等相关宏。如果写成的那个文件需要是unicode格式保存的，那么在创建文件时需要加入一个字节头。<br />CFile file; <br />    WCHAR szwBuffer[128];<br />    <br />    WCHAR *pszUnicode = L"Unicode string\n"; // unicode string<br />    CHAR *pszAnsi = "Ansi string\n"; // ansi string<br />    WORD wSignature = 0xFEFF;<br />    <br />    file.Open(TEXT("Test.txt"), CFile::modeCreate|CFile::modeWrite);<br />    <br />    file.Write(&amp;wSignature, 2);<br />    <br />    file.Write(pszUnicode, lstrlenW(pszUnicode) * sizeof(WCHAR)); <br />    // explicitly use lstrlenW function<br />    <br />    MultiByteToWideChar(CP_ACP, 0, pszAnsi, -1, szwBuffer, 128);<br />    <br />    file.Write(szwBuffer, lstrlenW(szwBuffer) * sizeof(WCHAR));<br />    <br />file.Close();<br />//以上这段代码在unicode和非unicode环境下都有效。这里显式的指明用Unicode来进行操作。<br />2.    在非unicode环境下，缺省调用的都是ANSI格式的字符串，此时TCHAR转换为CHAR类型的，除非显式定义WCHAR。所以在这个环境下，如果读取unicode文件，那么首先需要移动2个字节，然后读取得字符串需要用MultiByteToWideChar来转换，转换后字符串信息才代表unicode数据。<br />3.    在unicode环境下，缺省调用得都是unicode格式得字符串，也就是宽字符，此时TCHAR转换为WCHAR，相关得API函数也都调用宽字符类型的函数。此时读取unicode文件也和上面一样，但是读取得数据是WCHAR的，如果要转换成ANSI格式，需要调用WideCharToMultiByte。如果读取ANSI的，则不用移动两个字节，直接读取然后视需要转换即可。</p>
		<p>
				<br />某些语言（如韩语）必须在unicode环境下才能显示，这种情况下，在非unicode环境下开发，就算用字符串函数转换也不能达到显示文字的目的，因为此时调用得API函数是用ANSI的（虽然底层都是用UNICODE处理但是处理结果是按照程序员调用的API来显示的）。所以必须用unicode来开发。<br /></p>
<img src ="http://www.cppblog.com/liangbo/aggbug/6103.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/liangbo/" target="_blank">bo</a> 2006-04-23 18:21 <a href="http://www.cppblog.com/liangbo/archive/2006/04/23/6103.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于宏</title><link>http://www.cppblog.com/liangbo/archive/2006/03/29/4802.html</link><dc:creator>bo</dc:creator><author>bo</author><pubDate>Wed, 29 Mar 2006 13:21:00 GMT</pubDate><guid>http://www.cppblog.com/liangbo/archive/2006/03/29/4802.html</guid><wfw:comment>http://www.cppblog.com/liangbo/comments/4802.html</wfw:comment><comments>http://www.cppblog.com/liangbo/archive/2006/03/29/4802.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/liangbo/comments/commentRss/4802.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/liangbo/services/trackbacks/4802.html</trackback:ping><description><![CDATA[
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">关于</span>
				<span lang="EN-US">c</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">宏：</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo1; tab-stops: list 18.0pt">
				<span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">1．<span style="FONT: 7pt 'Times New Roman'">  </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">预编译器将程序正文中将所遇到的宏名展开成宏定义。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">#define PI 3.1415926</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo1; tab-stops: list 18.0pt">
				<span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">2．<span style="FONT: 7pt 'Times New Roman'">  </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以定义带参数的宏，具有模板的部分功能，但是最好将宏参数用括号括起来。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">#define MIN(a,b) (((a)&lt;(b))?(a):(b))</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo1; tab-stops: list 18.0pt">
				<span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">3．<span style="FONT: 7pt 'Times New Roman'">  </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">通过</span>
				<span lang="EN-US">##</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">宏运算符可以拼接起两个串。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">#define NAME</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">（</span>
				<span lang="EN-US">a,b</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">）</span>
				<span lang="EN-US">a##b</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo1; tab-stops: list 18.0pt">
				<span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">4．<span style="FONT: 7pt 'Times New Roman'">  </span></span>
				</span>
				<span lang="EN-US">#undef X </span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">保证不再有称为</span>
				<span lang="EN-US">X</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的有定义的宏。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l1 level1 lfo1; tab-stops: list 18.0pt">
				<span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">5．<span style="FONT: 7pt 'Times New Roman'">  </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">一种特殊的宏：条件编译。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">#ifdef MACRO_NAME</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">… …</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">#endif</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">意思是：除非应经定义了名为</span>
				<span lang="EN-US">MACRO_NAME</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的宏，否则</span>
				<span lang="EN-US">#ifdef</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">与</span>
				<span lang="EN-US">#endif</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">之间的语句将被忽略。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?>
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">C++</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中应该尽量避免使用宏：</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">1</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">．</span>
				<span lang="EN-US">#define PI 3.1415926</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以使用</span>
				<span lang="EN-US">const double PI=3.1415926</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">代替。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">2</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">．</span>
				<span lang="EN-US">#define MIN(a,b) (((a)&lt;(b))?(a):(b))</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以使用函数模板代替。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">template &lt;class T&gt;</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">inline T min(T a, T b)</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">{</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<span style="mso-tab-count: 1">       </span>return (a&lt;b)?a:b;</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">}</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">3.</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">用于拼接起两个串的宏和条件编译的宏仍然有其使用范围。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">宏的优点：</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt; mso-list: l0 level1 lfo2; tab-stops: list 18.0pt">
				<span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">1．<span style="FONT: 7pt 'Times New Roman'">  </span></span>
				</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">效率高，执行速度快。但是有的可以使用</span>
				<span lang="EN-US">C++</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的</span>
				<span lang="EN-US">inline</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">函数代替，仍然保持其执行效率。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">
						<o:p> </o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">宏的缺点：</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">1</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">．缺乏类型安全检查和作用域规则检查，编译器能看到的只是宏展开后的形式，所以在宏中的错误是在宏被展开之后报告的，而不是在它定义时，导致非常难以理解的错误信息。</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt">
				<span lang="EN-US">2</span>
				<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">．宏名不能重载，而且宏预处理器不能处理递归调用。</span>
		</p>
<img src ="http://www.cppblog.com/liangbo/aggbug/4802.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/liangbo/" target="_blank">bo</a> 2006-03-29 21:21 <a href="http://www.cppblog.com/liangbo/archive/2006/03/29/4802.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>