﻿<?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++博客-阿π</title><link>http://www.cppblog.com/lapcca/</link><description>专注于网络协议,系统底层,服务器软件</description><language>zh-cn</language><lastBuildDate>Thu, 23 Apr 2026 10:56:41 GMT</lastBuildDate><pubDate>Thu, 23 Apr 2026 10:56:41 GMT</pubDate><ttl>60</ttl><item><title>Linux下makefile教程</title><link>http://www.cppblog.com/lapcca/archive/2012/06/06/177838.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Wed, 06 Jun 2012 14:57:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2012/06/06/177838.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/177838.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2012/06/06/177838.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/177838.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/177838.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 转自陈皓 (CSDN)概述&#8212;&#8212;什么是makefile？或许很多Winodws的程序员都不知道这个东西，因为那些Windows的IDE都为你做了这个工作，但我觉得要作一个好的和 professional的程序员，makefile还是要懂。这就好像现在有这么多的HTML的编辑器，但如果你想成为一个专业人士，你还是要了解HTML的标识的含义。特别在Unix下的软件编译，你就不能不...&nbsp;&nbsp;<a href='http://www.cppblog.com/lapcca/archive/2012/06/06/177838.html'>阅读全文</a><img src ="http://www.cppblog.com/lapcca/aggbug/177838.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2012-06-06 22:57 <a href="http://www.cppblog.com/lapcca/archive/2012/06/06/177838.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Delete Gmail account</title><link>http://www.cppblog.com/lapcca/archive/2012/03/24/168825.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Sat, 24 Mar 2012 13:04:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2012/03/24/168825.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/168825.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2012/03/24/168825.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/168825.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/168825.html</trackback:ping><description><![CDATA[https://accounts.google.com/DeleteMailServiceConfirm<img src ="http://www.cppblog.com/lapcca/aggbug/168825.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2012-03-24 21:04 <a href="http://www.cppblog.com/lapcca/archive/2012/03/24/168825.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>c++ 中关于int，unsigned int , short的跨平台移植</title><link>http://www.cppblog.com/lapcca/archive/2011/04/15/144302.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Fri, 15 Apr 2011 06:02:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2011/04/15/144302.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/144302.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2011/04/15/144302.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/144302.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/144302.html</trackback:ping><description><![CDATA[int类型比较特殊，具体的字节数同机器字长和编译器有关。如果要保证移植性，尽量用__int16 __int32 __int64吧<br />__int16、__int32这种数据类型在所有平台下都分配相同的字节。所以在移植上不存在问题。<br /><span style="COLOR: red">所谓的不可移植是指：在一个平台上编写的代码无法拿到另一个平台上运行时，不能达到期望的运行结果</span>。<br />例如：在32为平台上（所谓32位平台是指通用寄存器的数据宽度是32）编写代码，int 类型分配4个字节，而在16位平台是则分配2个字节，那么在16位上编译出来的exe，<br />其中是为int分配2字节，而在32位平台上运行时，会按照4个字节来解析，显然会出错误的！！<br /><br />而对于非int行，目前为止，所有的类型分配的字节数都是兼容的，即不同平台对于同一个类型分配相同的字节数！！<br /><br /><span style="COLOR: red">建议：在代码中尽量避免使用int类型，根据不同的需要可以用short,long,unsigned int 等代替。<br /></span><br />下面是各个类型一览表【转】<br /><p>64位指的是cpu通用寄存器的数据宽度是64位的。</p><p></p><table class="FCK__ShowTableBorders" style="WIDTH: 578px; BORDER-COLLAPSE: collapse; HEIGHT: 550px" cellspacing="0" cellpadding="0" border="0"><tbody><tr style="HEIGHT: 12.75pt" height="17"><td class="xl30" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext 2pt double; BORDER-LEFT: windowtext 2pt double; WIDTH: 85pt; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 12.75pt; BACKGROUND-COLOR: silver" width="113" height="17"><font size="2"><strong>数据类型名称</strong></font></td><td class="xl32" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext 2pt double; BORDER-LEFT: windowtext; WIDTH: 41pt; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: silver" width="54"><font size="2"><strong>字节数</strong></font></td><td class="xl31" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext 2pt double; BORDER-LEFT: windowtext; WIDTH: 190pt; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: silver" width="253"><font size="2"><strong>别名</strong></font></td><td class="xl33" style="BORDER-RIGHT: windowtext 2pt double; BORDER-TOP: windowtext 2pt double; BORDER-LEFT: windowtext; WIDTH: 328pt; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: silver" width="437"><strong><font size="2">取值范围</font></strong></td></tr><tr style="HEIGHT: 12pt" height="16"><td class="xl34" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext 2pt double; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 12pt; BACKGROUND-COLOR: rgb(153,204,255)" height="16"><font size="2"><strong>int</strong></font></td><td class="xl25" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">*</font></td><td class="xl24" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">signed,signed int</font></td><td class="xl26" style="BORDER-RIGHT: windowtext 2pt double; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">由<a href="http://dev.21tx.com/os/" target="_blank"><font color="#3366cc"><u>操作系统</u></font></a>决定，即与操作系统的＂字长＂有关</font></td></tr><tr style="HEIGHT: 12pt" height="16"><td class="xl34" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext 2pt double; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 12pt; BACKGROUND-COLOR: rgb(153,204,255)" height="16"><font size="2"><strong>unsigned int</strong></font></td><td class="xl25" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">*</font></td><td class="xl24" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">unsigned</font></td><td class="xl26" style="BORDER-RIGHT: windowtext 2pt double; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">由操作系统决定，即与操作系统的＂字长＂有关</font></td></tr><tr style="HEIGHT: 12pt" height="16"><td class="xl34" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext 2pt double; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 12pt; BACKGROUND-COLOR: rgb(153,204,255)" height="16"><font size="2"><strong>__int8</strong></font></td><td class="xl25" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">1</font></td><td class="xl24" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">char,signed char</font></td><td class="xl26" style="BORDER-RIGHT: windowtext 2pt double; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">–128 到 127</font></td></tr><tr style="HEIGHT: 12.75pt" height="17"><td class="xl34" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext 2pt double; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 12.75pt; BACKGROUND-COLOR: rgb(153,204,255)" height="17"><font size="2"><strong>__int16</strong></font></td><td class="xl25" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">2</font></td><td class="xl24" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">short,short int,signed short int</font></td><td class="xl26" style="BORDER-RIGHT: windowtext 2pt double; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">–32,768 到 32,767</font></td></tr><tr style="HEIGHT: 12pt" height="16"><td class="xl34" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext 2pt double; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 12pt; BACKGROUND-COLOR: rgb(153,204,255)" height="16"><font size="2"><strong>__int32</strong></font></td><td class="xl25" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">4</font></td><td class="xl24" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">signed,signed int</font></td><td class="xl26" style="BORDER-RIGHT: windowtext 2pt double; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">–2,147,483,648 到 2,147,483,647</font></td></tr><tr style="HEIGHT: 12pt" height="16"><td class="xl34" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext 2pt double; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 12pt; BACKGROUND-COLOR: rgb(153,204,255)" height="16"><font size="2"><strong>__int64</strong></font></td><td class="xl25" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">8</font></td><td class="xl24" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">无</font></td><td class="xl26" style="BORDER-RIGHT: windowtext 2pt double; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">–9,223,372,036,854,775,808 到 9,223,372,036,854,775,807</font></td></tr><tr style="HEIGHT: 12pt" height="16"><td class="xl34" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext 2pt double; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 12pt; BACKGROUND-COLOR: rgb(153,204,255)" height="16"><font size="2"><strong>bool</strong></font></td><td class="xl25" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">1</font></td><td class="xl24" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">无</font></td><td class="xl26" style="BORDER-RIGHT: windowtext 2pt double; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">false 或 true</font></td></tr><tr style="HEIGHT: 12pt" height="16"><td class="xl34" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext 2pt double; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 12pt; BACKGROUND-COLOR: rgb(153,204,255)" height="16"><font size="2"><strong>char</strong></font></td><td class="xl25" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">1</font></td><td class="xl24" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">signed char</font></td><td class="xl26" style="BORDER-RIGHT: windowtext 2pt double; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">–128 到 127</font></td></tr><tr style="HEIGHT: 12pt" height="16"><td class="xl34" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext 2pt double; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 12pt; BACKGROUND-COLOR: rgb(153,204,255)" height="16"><font size="2"><strong>unsigned char</strong></font></td><td class="xl25" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">1</font></td><td class="xl24" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">无</font></td><td class="xl26" style="BORDER-RIGHT: windowtext 2pt double; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">0 到 255</font></td></tr><tr style="HEIGHT: 12pt" height="16"><td class="xl34" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext 2pt double; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 12pt; BACKGROUND-COLOR: rgb(153,204,255)" height="16"><font size="2"><strong>short</strong></font></td><td class="xl25" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">2</font></td><td class="xl24" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">short int,signed short int</font></td><td class="xl26" style="BORDER-RIGHT: windowtext 2pt double; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">–32,768 到 32,767</font></td></tr><tr style="HEIGHT: 12pt" height="16"><td class="xl34" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext 2pt double; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 12pt; BACKGROUND-COLOR: rgb(153,204,255)" height="16"><font size="2"><strong>unsigned short</strong></font></td><td class="xl25" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">2</font></td><td class="xl24" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">unsigned short int</font></td><td class="xl26" style="BORDER-RIGHT: windowtext 2pt double; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">0 到 65,535</font></td></tr><tr style="HEIGHT: 12pt" height="16"><td class="xl34" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext 2pt double; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 12pt; BACKGROUND-COLOR: rgb(153,204,255)" height="16"><font size="2"><strong>long</strong></font></td><td class="xl25" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">4</font></td><td class="xl24" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">long int,signed long int</font></td><td class="xl26" style="BORDER-RIGHT: windowtext 2pt double; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">–2,147,483,648 到 2,147,483,647</font></td></tr><tr style="HEIGHT: 12pt" height="16"><td class="xl34" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext 2pt double; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 12pt; BACKGROUND-COLOR: rgb(153,204,255)" height="16"><font size="2"><strong>long long</strong></font></td><td class="xl25" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">8</font></td><td class="xl24" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">none (but equivalent to __int64)</font></td><td class="xl26" style="BORDER-RIGHT: windowtext 2pt double; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">–9,223,372,036,854,775,808 到 9,223,372,036,854,775,807</font></td></tr><tr style="HEIGHT: 12pt" height="16"><td class="xl34" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext 2pt double; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 12pt; BACKGROUND-COLOR: rgb(153,204,255)" height="16"><font size="2"><strong>unsigned long</strong></font></td><td class="xl25" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">4</font></td><td class="xl24" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">unsigned long int</font></td><td class="xl26" style="BORDER-RIGHT: windowtext 2pt double; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">0 到 4,294,967,295</font></td></tr><tr style="HEIGHT: 12pt" height="16"><td class="xl34" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext 2pt double; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 12pt; BACKGROUND-COLOR: rgb(153,204,255)" height="16"><font size="2"><strong>enum</strong></font></td><td class="xl25" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">*</font></td><td class="xl24" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">无</font></td><td class="xl26" style="BORDER-RIGHT: windowtext 2pt double; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">由操作系统决定，即与操作系统的＂字长＂有关</font></td></tr><tr style="HEIGHT: 12pt" height="16"><td class="xl34" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext 2pt double; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 12pt; BACKGROUND-COLOR: rgb(153,204,255)" height="16"><font size="2"><strong>float</strong></font></td><td class="xl25" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">4</font></td><td class="xl24" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">无</font></td><td class="xl26" style="BORDER-RIGHT: windowtext 2pt double; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">3.4E +/- 38 (7 digits)</font></td></tr><tr style="HEIGHT: 12pt" height="16"><td class="xl34" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext 2pt double; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 12pt; BACKGROUND-COLOR: rgb(153,204,255)" height="16"><font size="2"><strong>double</strong></font></td><td class="xl25" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">8</font></td><td class="xl24" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">无</font></td><td class="xl26" style="BORDER-RIGHT: windowtext 2pt double; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">1.7E +/- 308 (15 digits)</font></td></tr><tr style="HEIGHT: 12pt" height="16"><td class="xl34" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext 2pt double; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 12pt; BACKGROUND-COLOR: rgb(153,204,255)" height="16"><font size="2"><strong>long double</strong></font></td><td class="xl25" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">8</font></td><td class="xl24" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">无</font></td><td class="xl26" style="BORDER-RIGHT: windowtext 2pt double; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent"><font size="2">1.7E +/- 308 (15 digits)</font></td></tr><tr style="HEIGHT: 12.75pt" height="17"><td class="xl35" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext 2pt double; BORDER-BOTTOM: windowtext 2pt double; HEIGHT: 12.75pt; BACKGROUND-COLOR: rgb(153,204,255)" height="17"><font size="2"><strong>wchar_t</strong></font></td><td class="xl28" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 2pt double; BACKGROUND-COLOR: transparent"><font size="2">2</font></td><td class="xl27" style="BORDER-RIGHT: windowtext 0.5pt solid; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 2pt double; BACKGROUND-COLOR: transparent"><font size="2">__wchar_t</font></td><td class="xl29" style="BORDER-RIGHT: windowtext 2pt double; BORDER-TOP: windowtext; BORDER-LEFT: windowtext; BORDER-BOTTOM: windowtext 2pt double; BACKGROUND-COLOR: transparent"><font size="2">0 到 65,535</font></td></tr></tbody></table><table height="273" width="100%" border="1"><tbody><tr><td width="22%" height="19">类型标识符</td><td width="19%" height="19">类型说明</td><td width="10%" height="19">长度<br />（字节）</td><td width="29%" height="19">范围</td><td width="20%" height="19">备注</td></tr><tr><td width="22%" height="18"><strong>char</strong></td><td width="19%" height="18">字符型</td><td width="10%" height="18">1</td><td width="29%" height="18">-128 ~ 127</td><td width="20%" height="18">-2<sup>7</sup> ~ (2<sup>7</sup> -1)</td></tr><tr><td width="22%" height="19"><strong>unsigned char</strong></td><td width="19%" height="19">无符字符型</td><td width="10%" height="19">1</td><td width="29%" height="19">0 ~ 255</td><td width="20%" height="19">0 ~ (2<sup>8</sup> -1)</td></tr><tr><td width="22%" height="18"><strong>short int</strong></td><td width="19%" height="18">短整型</td><td width="10%" height="18">2</td><td width="29%" height="18">-32768 ~ 32767</td><td width="20%" height="18">2<sup>-15</sup> ~ (2<sup>15</sup> - 1)</td></tr><tr><td width="22%" height="19"><strong>unsigned short int</strong></td><td width="19%" height="19">无符短整型</td><td width="10%" height="19">2</td><td width="29%" height="19">0 ~ 65535</td><td width="20%" height="19">0 ~ (2<sup>16</sup> - 1)</td></tr><tr><td width="22%" height="19"><strong>int</strong></td><td width="19%" height="19">整型</td><td width="10%" height="19">4</td><td width="29%" height="19">-2147483648 ~ 2147483647</td><td width="20%" height="19">-2<sup>31</sup> ~ (2<sup>31</sup> - 1)</td></tr><tr><td width="22%" height="19"><strong>unsigned int</strong></td><td width="19%" height="19">无符整型</td><td width="10%" height="19">4</td><td width="29%" height="19">0 ~ 4294967295</td><td width="20%" height="19">0 ~ (2<sup>32</sup>-1)</td></tr><tr><td width="22%" height="19"><strong>float</strong></td><td width="19%" height="19">实型（单精度）</td><td width="10%" height="19">4</td><td width="29%" height="19">1.18*10<sup>-38</sup> ~ 3.40*10<sup>38</sup></td><td width="20%" height="19">7位有效位</td></tr><tr><td width="22%" height="19"><strong>double</strong></td><td width="19%" height="19">实型（双精度）</td><td width="10%" height="19">8</td><td width="29%" height="19">2.23*10<sup>-308 </sup>~ 1.79*10<sup>308</sup></td><td width="20%" height="19">15位有效位</td></tr><tr><td width="22%" height="19"><strong>long double</strong></td><td width="19%" height="19">实型（长双精度）</td><td width="10%" height="19">10</td><td width="29%" height="19">3.37*10<sup>-4932</sup> ~ 1.18*10<sup>4932</sup></td><td width="20%" height="19">19位有效位<br /></td></tr></tbody></table><br /><br /><img src ="http://www.cppblog.com/lapcca/aggbug/144302.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2011-04-15 14:02 <a href="http://www.cppblog.com/lapcca/archive/2011/04/15/144302.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转帖】青年买不起房欲自杀折射四大悲哀 </title><link>http://www.cppblog.com/lapcca/archive/2010/12/01/135128.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Wed, 01 Dec 2010 01:38:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2010/12/01/135128.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/135128.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2010/12/01/135128.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/135128.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/135128.html</trackback:ping><description><![CDATA[青年买不起房欲自杀折射四大悲哀<br /><br />青年和女朋友一起从老家到大连打工，热恋中，女朋友告诉他没有房子别想结婚。青年没有太多的积蓄根本就买不起房子，在苦劝一个月无果后该青年不想活了，欲卧轨自杀。铁路民警发现准备寻短见的青年后，追出200多米将其“抓住”，经过开导终于使青年放弃了寻短见的念头。<br /><br />读罢此新闻，笔者心情无比沉重，因为这样即将发生的悲剧绝不是个案。笔者因业务关系认识一个做设计的年轻人，月薪8000的他在一家知名模具公司任设计部经理。在我们交往过程中，他给笔者的印象是勤奋、敬业、专业，为此，笔者非常看重他。有一天，我们相约谈设计方案时，笔者非常诧异地发现原本满头黑发的他，居然在短短半月没见的情况下变得头发花白、脸型清瘦、眼窝深陷。<br /><br />方案谈完，笔者请其共进晚餐，酒过三巡后，小伙子说出他被婚房逼得寝食难安，精神已近崩溃。因这样的事牵涉太多人，笔者也不便多说，只能劝其一定要保重自己的身体，至于感情、婚姻都可以和对方好好沟通的。餐后，笔者让司机送小伙子回住处，在其离开后，笔者心里久久难以平静。<br /><br />在中国这样处于经济高速发展、社会相对稳定、民众生活已趋富裕的社会，却有很多年青人被婚房而困扰，有的为了筹钱买房花光全家的积蓄、榨干父母的养老钱、借完朋友的生活费，再向银行举债得以成功当了房奴；有的因实在无能为力买不起房而与相恋的女友分手；有的为了买房精神崩溃；有的为了买房走上犯罪道路；有的为了买房自杀……<br /><br />在笔者看来，中国青年人因买不起房而背负沉重的精神负担，折射出中国社会诸多悲哀：<br /><br />悲哀一：畸高房价是逼青年人买不起婚房的最重要原因，而整个社会却鲜有充分认识。青年人结婚是一辈子的大事，在其结婚时能够拥有属于自己及伴侣的爱巢是几乎绝大多数青年人的梦想。而无情的现实却是，畸高房价令青年人的梦想不断破灭。尽管部分青年人通过各种途径、利用各种方法实现了拥有产权婚房的梦想，可其婚后却因此背负了沉重的债务负担。<br /><br />可大多数青年人却因买不起婚房而备受煎熬，一幕幕悲剧正在或即将上演。对于青年人买不起婚房，很多人不能理性看待。有些地产利益代言人说青年人买不起房是自己努力的不够；有些人说青年买不起房是其家人不能伸出援手；有些人说青年人就应该买不起房。这些人在表述这样的观点时，大多找出诸多理由。可他们却刻意淡化或忽略一个事实，那就是导致青年买不起房的最重要原因——畸高房价！<br /><br />对于青年买不起婚房，整个社会缺乏充分认识，民众表现出麻木、妥协、顺从。这从整个社会对于高房价的控诉与抵抗极其无力、民众为了子女结婚倾尽全家积蓄为其买房、尽管房价已然畸高民众依然为其买单等可以得到明证。<br /><br />悲哀二：荒唐的婚恋观、爱情观依然在深深影响当今社会。很多人认为，结婚就要拥有产权房，只有这样，婚姻基础才显得牢固。而在笔者看来，两个人之所以有结婚的想法（或打算），是双方感情发展到了要通过组建家庭共同生活的地步，是爱情的升华，是共同理想的结晶，是对美好生活的共同追求，也是对社会的责任。所有这一切，与双方是否拥有产权房没有任何关系。<br /><br />有人说，男人没有产权房的话，将很难说服女友与自己走向婚姻的殿堂。这一观点也是很荒谬的。我们要清楚自己要找的是共同生活的伴侣还是爱慕虚荣的过客，如果你的女友因没有产权房而不和你结婚，只能说明一个问题：你们的感情还处在较浅的层次，是非常脆弱的，还没有达到能步入婚姻殿堂的地步，这样，就需要进一步发展，或者，你们双方根本就不适合。<br /><br />当然，也有人会说，我爱女友胜过爱自己，她的要求我必须满足，赴汤蹈火亦在所不惜，何况买房子呢？诚然，对感情具有执着的精神是值得赞赏的，可如果不从自己的实际能力考虑盲目地通过购房来取悦女友是极不可取的。试想，为了满足女友这样的要求，你将付出多大的代价：有可能榨干父母的养老钱、背上沉重的债务包袱、个人信用受到很大影响、结婚后生活质量大打折扣……<br /><br />上述观点都是荒唐的婚姻观、爱情观在作怪。对于爱的理解，可以说是见仁见智。我一贯的观点是，一加一等于爱，即两个人心心相印，互相理解、互相支持、互相奉献，甘苦于共、相敬相随、偕老一生。爱是无私的、纯洁的，是不受金钱、物质、空间等非情感因素影响的。在爱情的天平上，承载的是关怀、奉献、崇敬与对美好生活的追求与向往。而诸如，金钱、产权房、力所不能及的物质需求不应成为爱情天平上的砝码。<br /><br />悲哀三：民众理性房屋消费教育严重缺失，政府及相关部门却没能为此做出足够的努力。近年来，由于房地产市场的持续火爆，很多本不具备买房实力的人在当时的市场状况下投入了买房者行列（在我们身边，这样的例子有很多），这种行为在一定程度上助推了房价的上涨。诚然，在当时看来，这种行为无可厚非，也确有一部份人因此获得了意想不到的收获。可却有更大一部分人因自己的购房行为背上了沉重的包袱，甚至有的人成为房奴。这就是非理性房屋消费观导致的恶果。<br /><br />对于房屋消费，民众大多是凭自己的判断，而政府及相关教育部门却没能做出理性的引导。无论是在教育机构，各类媒体还是文化作品中，我们都很少看到关于民众理性房屋消费的引导和宣传。而近年来笔者与牛刀、时寒冰等理性地产研究人士所发出的民众理性房屋消费的呼吁也因缺少媒体力推而淹没在网络海洋中。<br /><br />悲哀四：地产商用来诱导青年人买房的所谓“刚需理论”依然大行其道，对青年人依然产生足够的影响。房地产刚需是地产利益群体人为炮制出来旨在蒙蔽并用来欺诈民众的伪命题。所谓刚性需求，是相对于弹性需求而言的，即必须满足的需求。在生活中，我们必须喝水、吃饭、呼吸空气，这些均为刚性需求，因为如果一个人满足不了这些需求的话，就难以存活。而除了上述三种需求外，我们很难找出还有什么是必须要满足的需求。<br /><br />房地产利益群体在进行房产销售时，人为杜撰并刻意向民众灌输一个概念，即因自住、改善、结婚而买房行为属于刚性需求。事实果真如此吗？显然不是！在房价处畸高状态的今天，普通民众举全家乃至整个家族之力，甚至不惜透支未来十几、二十年的收入买房完全是一种异常奢侈的消费行为。这样的行为就相当于普通民众家庭餐餐吃山珍海味，就相当于普通民众大举借贷穿阿玛尼西服、背LV包、开宝马车。很显然，这样的购买行为完全没有必要，更何来刚性一说？再者说，结婚就一定得买房吗？租房生活就不能步入婚姻殿堂了？相信理性的人定然不认同结婚一定要买房的观点。 <!-- google_ad_section_end  --><img src ="http://www.cppblog.com/lapcca/aggbug/135128.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2010-12-01 09:38 <a href="http://www.cppblog.com/lapcca/archive/2010/12/01/135128.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++中的四种强制类型转换的区别 [转]</title><link>http://www.cppblog.com/lapcca/archive/2010/11/30/135081.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Tue, 30 Nov 2010 07:37:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2010/11/30/135081.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/135081.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2010/11/30/135081.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/135081.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/135081.html</trackback:ping><description><![CDATA[<p>使用标准C++的类型转换符：static_cast、dynamic_cast、reinterpret_cast、和const_cast。</p>
		<p> </p>
		<p>1 static_cast</p>
		<p>用法：static_cast &lt; type-id &gt; ( expression )     </p>
		<p>该运算符把expression转换为type-id类型，但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法：</p>
		<p>①用于类层次结构中基类和子类之间指针或引用的转换。</p>
		<p>  进行上行转换（把子类的指针或引用转换成基类表示）是安全的；</p>
		<p>  进行下行转换（把基类指针或引用转换成子类表示）时，由于没有动态类型检查，所以是不安全的。</p>
		<p>②用于基本数据类型之间的转换，如把int转换成char，把int转换成enum。这种转换的安全性也要开发人员来保证。</p>
		<p>③把空指针转换成目标类型的空指针。</p>
		<p>④把任何类型的表达式转换成void类型。</p>
		<p> </p>
		<p>注意：static_cast不能转换掉expression的const、volitale、或者__unaligned属性。</p>
		<p> </p>
		<p>2 dynamic_cast</p>
		<p>用法：dynamic_cast &lt; type-id &gt; ( expression )</p>
		<p>该运算符把expression转换成type-id类型的对象。Type-id必须是类的指针、类的引用或者void *；</p>
		<p>如果type-id是类指针类型，那么expression也必须是一个指针，如果type-id是一个引用，那么expression也必须是一个引用。</p>
		<p> </p>
		<p>dynamic_cast主要用于类层次间的上行转换和下行转换，还可以用于类之间的交叉转换。</p>
		<p>在类层次间进行上行转换时，dynamic_cast和static_cast的效果是一样的；</p>
		<p>在进行下行转换时，dynamic_cast具有类型检查的功能，比static_cast更安全。</p>
		<p>class B{</p>
		<p>public:</p>
		<p>       int m_iNum;</p>
		<p>       virtual void foo();</p>
		<p>};</p>
		<p> </p>
		<p>class D:public B{</p>
		<p>    public:</p>
		<p>       char *m_szName[100];</p>
		<p>};</p>
		<p> </p>
		<p>void func(B *pb){</p>
		<p>    D *pd1 = static_cast&lt;D *&gt;(pb);</p>
		<p>    D *pd2 = dynamic_cast&lt;D *&gt;(pb);</p>
		<p>}</p>
		<p> </p>
		<p>在上面的代码段中，如果pb指向一个D类型的对象，pd1和pd2是一样的，并且对这两个指针执行D类型的任何操作都是安全的；</p>
		<p>但是，如果pb指向的是一个B类型的对象，那么pd1将是一个指向该对象的指针，对它进行D类型的操作将是不安全的（如访问m_szName），</p>
		<p>而pd2将是一个空指针。</p>
		<p> </p>
		<p>另外要注意：B要有虚函数，否则会编译出错；static_cast则没有这个限制。</p>
		<p>这是由于运行时类型检查需要运行时类型信息，而这个信息存储在类的虚函数表（</p>
		<p>关于虚函数表的概念，详细可见&lt;Inside c++ object model&gt;）中，只有定义了虚函数的类才有虚函数表，</p>
		<p>没有定义虚函数的类是没有虚函数表的。</p>
		<p> </p>
		<p>另外，dynamic_cast还支持交叉转换（cross cast）。如下代码所示。</p>
		<p>class A{</p>
		<p>public:</p>
		<p>        int m_iNum;</p>
		<p>        virtual void f(){}</p>
		<p>};</p>
		<p> </p>
		<p>class B:public A{</p>
		<p>};</p>
		<p> </p>
		<p>class D:public A{</p>
		<p>};</p>
		<p> </p>
		<p>void foo(){</p>
		<p>    B *pb = new B;</p>
		<p>    pb-&gt;m_iNum = 100;</p>
		<p> </p>
		<p>    D *pd1 = static_cast&lt;D *&gt;(pb);    //compile error</p>
		<p>    D *pd2 = dynamic_cast&lt;D *&gt;(pb); //pd2 is NULL</p>
		<p>    delete pb;</p>
		<p>}</p>
		<p> </p>
		<p>在函数foo中，使用static_cast进行转换是不被允许的，将在编译时出错；而使用 dynamic_cast的转换则是允许的，结果是空指针。</p>
		<p> </p>
		<p>3 reinterpret_cast</p>
		<p>用法：reinterpret_cast&lt;type-id&gt; (expression)</p>
		<p>type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。</p>
		<p>它可以把一个指针转换成一个整数，也可以把一个整数转换成一个指针（先把一个指针转换成一个整数，</p>
		<p>在把该整数转换成原类型的指针，还可以得到原先的指针值）。</p>
		<p> </p>
		<p>该运算符的用法比较多。</p>
		<p> </p>
		<p>(static_cast .与. reinterpret_cast比较，见下面 )</p>
		<p> </p>
		<p>4 const_cast</p>
		<p>用法：const_cast&lt;type_id&gt; (expression)</p>
		<p>该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外， type_id和expression的类型是一样的。</p>
		<p>常量指针被转化成非常量指针，并且仍然指向原来的对象；</p>
		<p>常量引用被转换成非常量引用，并且仍然指向原来的对象；常量对象被转换成非常量对象。</p>
		<p> </p>
		<p>Voiatile和const类试。举如下一例：</p>
		<p>class B{</p>
		<p>public:</p>
		<p>     int m_iNum;</p>
		<p>}</p>
		<p>void foo(){</p>
		<p>const B b1;</p>
		<p>b1.m_iNum = 100;            //comile error</p>
		<p>B b2 = const_cast&lt;B&gt;(b1);</p>
		<p>b2. m_iNum = 200;           //fine</p>
		<p>}</p>
		<p>上面的代码编译时会报错，因为b1是一个常量对象，不能对它进行改变；</p>
		<p>使用const_cast把它转换成一个常量对象，就可以对它的数据成员任意改变。注意：b1和b2是两个不同的对象。</p>
		<p> </p>
		<p>== ===========================================</p>
		<p> </p>
		<p>== dynamic_cast .vs. static_cast </p>
		<p>== ===========================================</p>
		<p> </p>
		<p>class B { ... };</p>
		<p>class D : public B { ... };</p>
		<p> </p>
		<p>void f(B* pb)</p>
		<p>{</p>
		<p> </p>
		<p>D* pd1 = dynamic_cast&lt;D*&gt;(pb);</p>
		<p> </p>
		<p>D* pd2 = static_cast&lt;D*&gt;(pb); </p>
		<p>}</p>
		<p> </p>
		<p>If pb really points to an object of type D, then pd1 and pd2 will get the same value. They will also get the same value if pb == 0. </p>
		<p> </p>
		<p>If pb points to an object of type B and not to the complete D class, then dynamic_cast will know enough to return zero. However, static_cast relies on the programmer’s assertion that pb points to an object of type D and simply returns a pointer to that supposed D object. </p>
		<p> </p>
		<p>即dynamic_cast可用于继承体系中的向下转型，即将基类指针转换为派生类指针，比static_cast更严格更安全。dynamic_cast在执行效率上比static_cast要差一些，但static_cast在更宽上范围内可以完成映射，这种不加限制的映射伴随着不安全性。static_cast覆盖的变换类型除类层次的静态导航以外，还包括无映射变换、窄化变换(这种变换会导致对象切片,丢失信息)、用VOID*的强制变换、隐式类型变换等... </p>
		<p> </p>
		<p>== ===========================================</p>
		<p>== static_cast .vs. reinterpret_cast</p>
		<p>== ================================================</p>
		<p> </p>
		<p>reinterpret_cast是为了映射到一个完全不同类型的意思，这个关键词在我们需要把类型映射回原有类型时用到它。我们映射到的类型仅仅是为了故弄玄虚和其他目的，这是所有映射中最危险的。(这句话是C++编程思想中的原话)</p>
		<p> </p>
		<p>static_cast 和 reinterpret_cast 操作符修改了操作数类型。它们不是互逆的； static_cast 在编译时使用类型信息执行转换，在转换执行必要的检测(诸如指针越界计算, 类型检查). 其操作数相对是安全的。另一方面；reinterpret_cast 仅仅是重新解释了给出的对象的比特模型而没有进行二进制转换， 例子如下：</p>
		<p> </p>
		<p>int n=9; double d=static_cast &lt; double &gt; (n); </p>
		<p> </p>
		<p>上面的例子中, 我们将一个变量从 int 转换到 double。 这些类型的二进制表达式是不同的。 要将整数 9 转换到 双精度整数 9，static_cast 需要正确地为双精度整数 d 补足比特位。其结果为 9.0。而reinterpret_cast 的行为却不同: </p>
		<p> </p>
		<p>int n=9;</p>
		<p>double d=reinterpret_cast&lt;double &amp; &gt; (n);</p>
		<p> </p>
		<p>这次, 结果有所不同. 在进行计算以后, d 包含无用值. 这是因为 reinterpret_cast 仅仅是复制 n 的比特位到 d, 没有进行必要的分析.</p>
		<p> </p>
		<p>因此, 你需要谨慎使用 reinterpret_cast. </p><img src ="http://www.cppblog.com/lapcca/aggbug/135081.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2010-11-30 15:37 <a href="http://www.cppblog.com/lapcca/archive/2010/11/30/135081.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>成都地铁规划[图]</title><link>http://www.cppblog.com/lapcca/archive/2010/11/30/135061.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Tue, 30 Nov 2010 03:33:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2010/11/30/135061.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/135061.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2010/11/30/135061.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/135061.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/135061.html</trackback:ping><description><![CDATA[<img src="http://www.cppblog.com/images/cppblog_com/lapcca/13342/o_metro.jpg" /><img src ="http://www.cppblog.com/lapcca/aggbug/135061.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2010-11-30 11:33 <a href="http://www.cppblog.com/lapcca/archive/2010/11/30/135061.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>linux makefile编写</title><link>http://www.cppblog.com/lapcca/archive/2010/11/26/134714.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Fri, 26 Nov 2010 03:39:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2010/11/26/134714.html</guid><description><![CDATA[<div class="t_msgfont" id="postmessage_4926">一、Makefile的规则<br /><br />在讲述这个Makefile之前，还是让我们先来粗略地看一看Makefile的规则。<br /><br />target ... : prerequisites ...<br /><br />command<br /><br />...<br /><br />...<br /><br />target也就是一个目标文件，可以是Object File，也可以是执行文件。<br /><br />prerequisites就是，要生成那个target所需要的文件或是目标。<br /><br />command也就是make需要执行的命令。（任意的Shell命令）<br /><br />这是一个文件的依赖关系，也就是说，target这一个或多个的目标文件依赖于prerequisites中的文件，其生成规则定义在 command中。说白一点就是说，prerequisites中如果有<br /><br />一个以上的文件比target文件要新的话，command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。<br /><br />二、一个示例<br /><br />正如前面所说的，如果一个工程有3个头文件，和8个C文件，我们为了完成前面所述的那三个规则，我们的Makefile应该是下面的这个样子的。<br /><br />edit : main.o kbd.o command.o display.o \<br /><br />insert.o search.o files.o utils.o<br /><br />        gcc -o edit main.o kbd.o command.o display.o \<br /><br />insert.o search.o files.o utils.o<br /><br /><br />main.o : main.c defs.h<br /><br />        gcc -c main.c<br /><br />kbd.o : kbd.c defs.h command.h<br /><br />        gcc -c kbd.c<br /><br />command.o : command.c defs.h command.h<br /><br />        gcc -c command.c<br /><br />display.o : display.c defs.h buffer.h<br /><br />        gcc -c display.c<br /><br />insert.o : insert.c defs.h buffer.h<br /><br />        gcc -c insert.c<br /><br />search.o : search.c defs.h buffer.h<br /><br />        gcc -c search.c<br /><br />files.o : files.c defs.h buffer.h command.h<br /><br />        gcc -c files.c<br /><br />utils.o : utils.c defs.h<br /><br />        gcc -c utils.c<br /><br />clean :<br /><br />        rm edit main.o kbd.o command.o display.o insert.o search.o files.o utils.o<br /><br />反斜杠（\）是换行符的意思。这样比较便于Makefile的易读。我们可以把这个内容保存在文件为“Makefile”或“makefile”的文件中，然后在该目录下直接输入命令“make”就<br /><br />可以生成执行文件edit。如果要删除执行文件和所有的中间目标文件，那么，只要简单地执行一下 “make clean”就可以了。<br /><br /><br />在这个makefile中，目标文件（target）包含：执行文件edit和中间目标文件（*.o），依赖文件（prerequisites）就是冒号后面的那些 .c 文件和 .h文件。每一个 .o 文件都有<br /><br />一组依赖文件，而这些 .o 文件又是执行文件 edit 的依赖文件。依赖关系的实质上就是说明了目标文件是由哪些文件生成的，换言之，目标文件是哪些文件更新的。<br /><br /><br />在定义好依赖关系后，后续的那一行定义了如何生成目标文件的操作系统命令，一定要以一个Tab键作为开头。记住，make并不管命令是怎么工作的，他只管执行所定义的命令。<br /><br />make会比较targets文件和prerequisites文件的修改日期，如果prerequisites文件的日期要比 targets文件的日期要新，或者target不存在的话，那么，make就会执行后续定义的<br /><br />命令。<br /><br /><br />这里要说明一点的是，clean不是一个文件，它只不过是一个动作名字，有点像C语言中的lable一样，其冒号后什么也没有，那么，make就不会自动去找文件的依赖性，也就不会自<br /><br />动执行其后所定义的命令。要执行其后的命令，就要在make命令后明显得指出这个lable的名字。这样的方法非常有用，我们可以在一个makefile中定义不用的编译或是和编译无关<br /><br />的命令，比如程序的打包，程序的备份，等等。<br /><br /><br />三、make是如何工作的<br /><br /><br />在默认的方式下，也就是我们只输入make命令。那么，<br /><br /><br />1、make会在当前目录下找名字叫“Makefile”或“makefile”的文件。<br /><br />2、如果找到，它会找文件中的第一个目标文件（target），在上面的例子中，他会找到“edit”这个文件，并把这个文件作为最终的目标文件。<br /><br />3、如果edit文件不存在，或是edit所依赖的后面的 .o 文件的文件修改时间要比edit这个文件新，那么，他就会执行后面所定义的命令来生成edit这个文件。<br /><br />4、如果edit所依赖的.o文件也不存在，那么make会在当前文件中找目标为.o文件的依赖性，如果找到则再根据那一个规则生成.o文件。<br /><br />5、当然，你的C文件和H文件是存在的啦，于是make会生成 .o 文件，然后再用 .o 文件生命make的终极任务，也就是执行文件edit了。<br /><br /><br />这就是整个make的依赖性，make会一层又一层地去找文件的依赖关系，直到最终编译出第一个目标文件。在找寻的过程中，如果出现错误，比如最后被依赖的文件找不到，那么<br /><br />make就会直接退出，并报错，而对于所定义的命令的错误，或是编译不成功，make根本不理。make只管文件的依赖性，即，如果在我找了依赖关系之后，冒号后面的文件还是不在<br /><br />，那么对不起，我就不工作啦。<br /><br /><br />通过上述分析，我们知道，像clean这种，没有被第一个目标文件直接或间接关联，那么它后面所定义的命令将不会被自动执行，不过，我们可以显示要 make执行。即命令——<br /><br />“make clean”，以此来清除所有的目标文件，以便重编译。<br /><br /><br />于是在我们编程中，如果这个工程已被编译过了，当我们修改了其中一个源文件，比如file.c，那么根据我们的依赖性，我们的目标file.o会被重编译（也就是在这个依性关系后<br /><br />面所定义的命令），于是file.o的文件也是最新的啦，于是file.o的文件修改时间要比edit要新，所以edit 也会被重新链接了。<br /><br /><br />而如果我们改变了“command.h”，那么，kdb.o、command.o和files.o都会被重编译，并且，edit会被重链接。<br /><br /><br />四、makefile中使用变量<br /><br /><br />在上面的例子中，先让我们看看edit的规则：<br /><br /><br />edit : main.o kbd.o command.o display.o insert.o search.o files.o utils.o<br /><br />        gcc -o edit main.o kbd.o command.o display.o insert.o search.o files.o utils.o<br /><br />我们可以看到[.o]文件的字符串被重复了两次，如果我们的工程需要加入一个新的[.o]文件，那么我们需要在两个地方加（应该是三个地方，还有一个地方在clean中）。当然，我<br /><br />们的makefile并不复杂，所以在两个地方加也不累，但如果makefile变得复杂，那么我们就有可能会忘掉一个需要加入的地方，而导致编译失败。所以，为了makefile的易维护，<br /><br />在makefile中我们可以使用变量。makefile的变量也就是一个字符串，理解成C语言中的宏可能会更好。<br /><br />比如，我们声明一个变量，叫objects, OBJECTS, objs, OBJS, obj, 或是 OBJ，反正不管什么啦，只要能够表示obj文件就行了。我们在makefile一开始就这样定义：<br /><br />objects = main.o kbd.o command.o display.o \<br /><br />insert.o search.o files.o utils.o<br /><br /><br />于是，我们就可以很方便地在我们的makefile中以“$(objects)”的方式来使用这个变量了，于是我们的改良版makefile就变成下面这个样子：<br /><br /><br />objects = main.o kbd.o command.o display.o \<br /><br />insert.o search.o files.o utils.o<br /><br />edit : $(objects)<br /><br />        gcc -o edit $(objects)<br /><br />main.o : main.c defs.h<br /><br />        gcc -c main.c<br /><br />kbd.o : kbd.c defs.h command.h<br /><br />        gcc -c kbd.c<br /><br />command.o : command.c defs.h command.h<br /><br />        gcc -c command.c<br /><br />display.o : display.c defs.h buffer.h<br /><br />        gcc -c display.c<br /><br />insert.o : insert.c defs.h buffer.h<br /><br />        gcc -c insert.c<br /><br />search.o : search.c defs.h buffer.h<br /><br />        gcc -c search.c<br /><br />files.o : files.c defs.h buffer.h command.h<br /><br />        gcc -c files.c<br /><br />utils.o : utils.c defs.h<br /><br />        gcc -c utils.c<br /><br />clean :<br /><br />        rm edit $(objects)<br /><br /><br /><br /><br /><br />于是如果有新的 .o 文件加入，我们只需简单地修改一下 objects 变量就可以了。<br /><br /><br />五、让make自动推导<br /><br /><br /><br />GNU的make很强大，它可以自动推导文件以及文件依赖关系后面的命令，于是我们就没必要去在每一个[.o]文件后都写上类似的命令，因为，我们的make会自动识别，并自己推导命<br /><br />令。<br /><br /><br /><br />只要make看到一个[.o]文件，它就会自动的把[.c]文件加在依赖关系中，如果make找到一个whatever.o，那么 whatever.c，就会是whatever.o的依赖文件。并且 cc -c <br /><br />whatever.c 也会被推导出来，于是，我们的makefile再也不用写得这么复杂。那么新的makefile将变为。<br /><br />objects = main.o kbd.o command.o display.o \<br /><br />insert.o search.o files.o utils.o<br /><br /><br /><br />edit : $(objects)<br /><br />cc -o edit $(objects)<br /><br />main.o : defs.h<br /><br />kbd.o : defs.h command.h<br /><br />command.o : defs.h command.h<br /><br />display.o : defs.h buffer.h<br /><br />insert.o : defs.h buffer.h<br /><br />search.o : defs.h buffer.h<br /><br />files.o : defs.h buffer.h command.h<br /><br />utils.o : defs.h<br /><br />clean :<br />        rm edit $(objects)<br /><br /><br /><br />六、清空目标文件的规则<br /><br /><br /><br />每个Makefile中都应该写一个清空目标文件（.o和执行文件）的规则，这不仅便于重编译，也很利于保持文件的清洁。其风格如下：<br /><br />clean:<br /><br />        rm edit $(objects)<br /><br /><br />更为稳健的做法是：<br /><br /><br /><br />.PHONY : clean<br /><br />clean :<br /><br />-rm edit $(objects)<br /><br />.PHONY意思表示clean是一个“伪目标”，。而在rm命令前面加了一个小减号的意思就是，也许某些文件出现问题，但不要管，继续做后面的事。当然，clean的规则不<br /><br />要放在文件的开头，不然，这就会变成make的默认目标。不成文的规矩是——“clean从来都是放在文件的最后”。<br /><br />转自:http://bbs.dameng.com/viewthread.php?tid=1506</div><img src ="http://www.cppblog.com/lapcca/aggbug/134714.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2010-11-26 11:39 <a href="http://www.cppblog.com/lapcca/archive/2010/11/26/134714.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>c++ 枚举网页</title><link>http://www.cppblog.com/lapcca/archive/2010/11/22/134277.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Mon, 22 Nov 2010 07:34:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2010/11/22/134277.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/134277.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2010/11/22/134277.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/134277.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/134277.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: #include 				&lt;				stdio.h				&gt;																#include 				&lt;				tchar.h				&gt;																#include				&lt;				iostream				&gt;																#include...&nbsp;&nbsp;<a href='http://www.cppblog.com/lapcca/archive/2010/11/22/134277.html'>阅读全文</a><img src ="http://www.cppblog.com/lapcca/aggbug/134277.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2010-11-22 15:34 <a href="http://www.cppblog.com/lapcca/archive/2010/11/22/134277.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设计winsock服务器需要注意的几个问题</title><link>http://www.cppblog.com/lapcca/archive/2010/11/12/133421.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Fri, 12 Nov 2010 06:04:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2010/11/12/133421.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/133421.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2010/11/12/133421.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/133421.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/133421.html</trackback:ping><description><![CDATA[<p>6.2.1 接受连接的方法 </p>
		<p>Winsock 扩展函数 AcceptEx 是唯一能够使用重叠 I/O 接受客户连接的函数。下面主要深入探讨使用该函数接收连接的问题。 </p>
		<p>前面已经讨论过，当客户连接进来时，服务器需要创建一个套接字来负责维护与一个客户端的会话。使用 AcceptEx 函数之前必须创建一些套接字，并且这些套接字必须是未绑定、未连接的，即使它们可能在调用 TransmitFile, TransmitPackets, 或 DisconnectEx 后可以重用。 </p>
		<p>响应服务器必须总是具有足够的 AcceptEx 在站岗，以便在有客户连接请求时调用。但是，并没有具体的数量能够保证服务器能够立即响应连接。我们知道在调用 listen 将监听套接字置于监听状态后， TCP/IP 堆栈会自动接受到来的连接，直到达到 listen 的 backlog 参数设定的限制。对于 Windows NT 服务器而言，支持的 backlog 的最大值为 200 。如果服务器投递了 15 个 AcceptEx 调用，然后突然有 50 个客户请求连接服务器，它们的连接请求都不会遭到拒绝。服务器投递的 AcceptEx I/O 会满足前面的 15 个连接，剩下的 35 个连接都被系统默认连接了。检查一下 backlog 的值发现，系统还有能力默认接受 165 个连接。之后，如果服务器投递 AcceptEx 调用，它们会立即成功返回，因为系统会将默认接收的连接放入 “ 等待连接队列 ” 中。 </p>
		<p>服务器的特性是决定要投递多少个 AcceptEx 操作的重要因素。例如，希望处理大量短时间即时连接的客户要比处理少量长时间连接的客户投递更多的 AcceptEx I/O 。一个好的策略是允许 AcceptEx 的调用数量在最小值和最大值之间变化。具体做法是，应用程序跟踪未决的 AcceptEx I/O 的数量，当一个或多个 I/O 完成使这个未决 I/O 数量变得比最小值还小时，就再投递额外的 AcceptEx I/O 。 </p>
		<p>在 Windows 2000 和以后的 Windows 操作系统版本中， Winsock 提供了一种机制，用来确定应用程序是否投递了足够的 AcceptEx 调用。创建监听套接字时，使用 WSAEventSelect 函数为监听套接字关联一个事件对象，注册 FD_ACCEPT 事件。如果投递的 AcceptEx 操作用完，但是仍有客户请求接入（系统根据 backlog 值决定是否接受这些连接），事件对象就是受信，说明应该投递额外的 AcceptEx 操作了。这实际上还是利用事件对象来使调用线程处于一种 “ 可警告状态 ” ，当有客户连接请求时，就根据当前 AcceptEx 操作是否用完来警告（通知）是否需要投递新的 AcceptEx 操作来处理新的客户连接。 </p>
		<p>使用 AcceptEx 处理连接的另外一个功能就是在处理连接时还可以接收用户发来的第一块数据（前提是为 AcceptEx 提供了接收缓冲区），这对于那些请求连接的同时发送了一些数据过来的客户来说很适用。但是，此时，除非接收连接的同时接收到了客户发送过来的一些数据，否则 AcceptEx 是不会返回的。 </p>
		<p>为了满足客户的需求，服务器不得不投递更多的接受 I/O ，这会占用大量的系统资源。如果客户仅调用 connect 函数连接服务器，长时间既不发送数据，也不关闭连接，就可能造成 AcceptEx 投递的大量重叠 I/O 操作不能返回。这就是 “ 恶意连接 ” 。为此，服务器应该记录每个 AcceptEx 投递的未决 I/O, 定时扫描它们，设置 SO_CONNECT_TIME 参数调用 getsockopt 检查它们连接的时间，如果超时，就将连接关闭。如果使用 WSAEventSelect 模型来通知有连接事件，则当事件受信时，是检查客户套接字（ AcceptSocket ）是否真正连接了。 </p>
		<p>每当调用 AcceptEx 接受客户端连接时，它也在等待接受客户发送过来的第一个数据块，这时不允许投递另外一个 AcceptEx 。当 AcceptEx 返回后，如果事件对象再次受信则表明有新的连接到来。需要注意的是，无论何时，千万不要关闭一个调用 AcceptEx 还没有返回的套接字（ AcceptSocket ），因为这会导致内存泄露。因为从内部执行逻辑看，当没有连接的套接字句柄被关闭时，调用 AcceptEx 所涉及到的内核模式的数据结构并不会清除掉，直到有新的连接建立或者监听套接字被关闭。 </p>
		<p>尽管在一个等待完成通知的工作者线程中，投递一个 AcceptEx 操作，看起来既简单又合情合理，但是应尽量避免这样做，因为创建套接字还是很耗费资源的。另外，也不要在工作者线程中进行任何复杂的计算，以便处理器可以尽快的在接到完成通知后进行后续处理。创建套接字耗费资源的一个原因在于 Winsock 2.0 本身的架构很复杂，成功地创建一个套接字可能需要调用很多内核服务。因此，服务器应该在单独线程中创建套接字，投递 AcceptEx 操作。当调用线程投递的 AcceptEx 重叠操作完成时，一个受信的事件将会通知处理线程。 </p>
		<p>6.2.2 数据传输问题 </p>
		<p>数据传输是通信程序执行的核心操作。当一个客户与服务器建立连接后，它们的主要工作就是传输数据，因为数据是信息的表示。由上一节几种 I/O 模型的性能测试分析可知，当连接数量很大时，数据吞吐量是一个重要的性能考核指标。 </p>
		<p>从性能角度考虑，所有的数据传输最好都应采用重叠 I/O 处理。默认情况下，系统为每个 socket 分配一个的接受缓冲区和一个发送缓冲区，用来缓存接收和发送的数据。但在重叠 I/O 中，这些缓冲区往往不用，可以传递参数 SO_SNDBUF 或 SO_RCVBUF 调用 setsockopt ，来将它们设置为 0 。 </p>
		<p>让我们来看看，当发送缓冲区没有设置为 0 时，系统是怎么处理一个典型的 send 操作的。当一个应用程序调用 send 函数时，如果有充足的缓冲空间，需要发送的数据将被拷贝到套接字的发送缓冲区， send 函数立即成功返回，并且一个完成通知被抛出。另外一个方面，如果套接字的发送缓冲区已满，则应用程序提供的发送缓冲区被锁定，再次对 send 函数的调用将会返回 WSA_IO_PENDING 错误。当发送缓冲区中的数据被处理（例如，提交给传输层处理）时， Winsock 实际上直接处理锁定在缓冲区中的数据，也即绕过套接字的发送缓冲区，直接从应用程序缓冲区中提交数据给传输层。 </p>
		<p>接收数据的情况恰好相反。当一个重叠的 receive 请求抛出后，如果数据已经接收成功，它会被缓存在套接字接收缓冲区。数据会拷贝到应用程序缓冲区（直到饱和）。 receive 调用返回，并且一个完成通知被抛出。当套接字缓冲区被设置为空时，如果调用重叠的 receive 操作将返回 WSA_IO_PENDING 错误。当有数据到达时，它将绕过套接字缓冲区而直接被拷贝到应用程序缓冲区。 </p>
		<p>设置单套接字缓冲区为 0 ，并不能提高性能，因为只要一直有大量的重叠接发请求被抛出，就不会有额外的内存拷贝。设置套接字发送缓冲区为空比设置套接字接收缓冲区为空对系统的性能影响要小。因为应用程序的发送缓冲区会被经常锁定直到它被提交给传输层处理。然而，若将接收缓冲区设置为 0 ，并且没有重叠的 receive 调用，任何传进来的数据只能缓存在传输层。传输层驱动程序只会缓存滑动窗口尺寸的数据，即 17KB— 传输层可以分配的缓冲区大小的上限。实际的缓冲区要比 17KB 小。传输层缓冲区（针对一次连接）是在非分页池之外分配的，这意味着，当服务建立了 1000 个连接时，即使没有抛出 receive 请求，非分页池中也会分配 17MB 的内存。而非分页池是很珍贵的资源，除非服务器可以保证总是有接收请求抛出，否则套接字接收缓冲区应该不需设置。 </p>
		<p>只有在一些特殊情况下，对套接字接收缓冲区不予设置将会导致性能降低。考虑服务器需要处理成千上万个客户连接，而每个连接上又都没有投递 receive 请求的情况，如果客户端零星地发送数据过来，传输进来的数据将被缓存在套接字接收缓冲区中。当服务器处理一个 receive 重叠 I/O 时，它会做一些不必要的工作。当完成通知到达时，重叠操作会处理一个 I/O 请求包（ IRP ）。在这种情形下，服务器不能保留很多抛出的 receive 请求。因此，最好使用简单的非阻塞接收函数。 </p>
		<p>6.3 内存资源管理问题 </p>
		<p>由于机器硬件条件所限，系统资源是有限的，因此不得不考虑内存资源的管理问题。从上一节对不同 I/O 模型进行的性能测试结果分析可知，维持大规模的通信连接，不仅会耗费掉大量内存，而且对 CPU 的占用也是很高的。 </p>
		<p>对于配置比较高的服务器而言，处理成千上万个连接并不成问题。但是随着连接量的剧增，内存资源的限制将逐渐凸现。最有可能遇到的两个限制因素就是锁定页和非分页池。锁定页的限制不是太严重，更应该避免的是非分页池被耗尽。每一次调用重叠的 send 或 receive 请求，提交的缓冲区都可能被锁住。当内存被锁定时，它就不能从物理内存换出。操作系统对锁定内存的数量是有限制的，当达到极限时，重叠操作将会返回 WSAENOBUFS 错误。如果服务器在每个连接上投递多个重叠接收操作，随着客户连接数量的增多，极限就会达到。如果期望服务器能够处理高并发通信，服务器可以在每个连接上投递一个 0 字节的接受操作，这样就不会有内存锁定。 0 字节的接受完成以后，服务器可以简单地执行一个非阻塞的接收函数来获取缓存在套接字接收缓冲区中的所有数据。当非阻塞接收调用返回 WSAEWOULDBLOCK 时，就表示不再有未决的数据了。这种方法非常适合用来设计那些希望通过牺牲每个套接字上的吞吐率来获取更大规模并发连接的服务器。 </p>
		<p>当然，最好还要了解客户端与服务器通信的方式。在上面的例子中，当 0 字节的接收完成后，再投递一个异步接收操作，将接收到所有缓存在套接字接收缓冲区中的数据。如果服务器知道客户端将会连续不断发送数据，那么当 0 字节的接收完成后，假如客户端将发送大数据块（超过单套接字缓冲区 8KB 的容量）过来，服务器将抛出一个或多个重叠的接收操作。 </p>
		<p>另外一个需要重点考虑的问题就是系统所需页的数量。当系统锁定传递给重叠操作的内存时，它是在页边界上进行的。在 x86 体系结构上，内存页的大小为 4KB 。如果一个操作投递了 1KB 的缓冲区，系统实际上会为它锁定 4KB 大小的内存块。为避免这种浪费，重叠发送和接收缓冲区的大小应该是页大小的倍数。可以使用 GetSystemInfo 这个 API 来获知当前系统页的大小。 </p>
		<p>如果突破非分页池极限，将会导致更严重的错误，并且很难恢复。非分页池是内存的一部分，它常驻内存，并且永远不会被交换出去。内核模式的系统组件，如驱动程序，通常使用非分页池，其中包括 Winsock 和协议驱动程序，例如 tcpip.sys 。每个套接字的创建将消耗一小部分非分页池，用于维持套接字状态信息。当套接字绑定到一个地址后， TCP/IP 堆栈将分配额外的非分页池来保存本地地址的信息。当一个对等套接字接入后， TCP/IP 堆栈也将分配部分非分页池来保存远程地址信息。基本上，一个建立连接的套接字占用 2KB 非分页池内存 , 而 accept 或 AcceptEx 返回的套接字则占用 1.5KB 非分页池内存。之所以出现这个区别，是因为服务器本地地址信息已经存储在监听套接字中，故 accept 或 AcceptEx 返回的套接字只需保存远程主机地址信息。此外，每个在套接字上投递的重叠操作都需要给 I/O 请求包（ IRP ）分配内存，一个 IRP 使用大约 500B 非分页池内存。 </p>
		<p>从以上分析可以看出，为每个连接分配的非分页池内存并不是很大。然而，随着客户连接量逐增，服务器对非分页池的使用将是非常大的。考虑运行在只有 1GB 物理内存的 Windows 2000 或以后版本 Windows 系统上的服务器，将有 256MB 的内存非配给非分页池。通常，非分页池大小是机器物理内存的 1/4 ， Windows 2000 及以后版本的 Windows 系统上，非分页池大小为 256MB （ /1GB ），而 Windows NT 4.0 限制为 128MB （ 1GB ）。拥有 256MB 的非分页池的服务器可以支持 50,000 或更大的连接量。但是必须限制重叠的 accept 数量，以及在已经建立连接的重叠收发操作。在这个例子中，如果已经建立连接的套接字，按每个 1.5KB 计算，将耗费 75MB 的非分页池内存。如果采用了上面提及的投递 0 字节接收的方法，这样为每个连接分配的 IRP 将占用 25MB 的非分页池内存。 </p>
		<p>如果系统耗尽了非分页池，会有两种可能的后果。在最好的情况下， Winsock 调用将返回 WSAENOBUFS 错误。最糟糕的情况是系统崩溃，这种情况通常是系统没能正确处理内存非配的问题造成的。没有一种可行的方案能够恢复非分页池耗尽的错误，并且也没有可行的方案来监视非分页池可分配的大小，因为非分页池耗尽导致系统崩溃。 </p>
		<p>由以上探讨，可以得出结论，没有一种方法可以确定服务器到底支持多大的并发连接和重叠操作，并且也不可能准确地获知非分页池是否耗尽或者锁定内存页数超过极限。因为它们都将导致 Winsock 调用都返回相同的错误 —WSAENOBUFS 。因为以上因素，针对服务器的测试必须测试不同数量的连接情况以及重叠操作完成情况，以便在并发通信规模和数据吞吐率这两个指标之间选择一种折中的方案。如果在方案中强加限制，以防止服务器耗尽非分页池，则返回 WSAENOBUFS 错误时，我们就知道是因为超过了锁定页的限制。并且可以以一种更优化的处理方式编写程序，如进一步限制一些待决的操作或关闭某些连接。 </p>
		<p>包重新排序问题 </p>
		<p>这个问题与伸缩性没有多大关联，但是却是实际通信中不得不考虑的一个问题，因为它涉及到能否正确通信的问题。 </p>
		<p>虽然使用完成端口的 I/O 操作总是会按照它们被提交的顺序完成，但是线程调度问题可能会导致关联到完成端口上的工作不能按正常顺序完成。例如，有两个 I/O 工作线程，应该接收 “ 字节块 1 ，字节块 2 ，字节块 3” ，但是你可能以错误顺序接收这 3 个字节块： “ 字节块 2 ，字节块 1 ，字节块 3” 。这也意味着在完成端口上投递发送请求发送数据时，数据实际也会以错误顺序被发送出去。 </p>
		<p>当然，如果只使用一个工作线程，仅提交一个 I/O 调用，是不存在顺序问题的。因为同一时刻，一个工作线程只能处理一个 I/O 操作。但是，这样就没有发挥出完成端口的真正优点。 </p>
		<p>如第 3 章《自定义应用层通信协议》所述，一个简单的解决方法就是为每个封包添加一个协议头。协议头主要是一个封包的实际字节数，如自定义 Package 包的第一个字段 m_nCmdLen 就是这个包占用的字节数。通信的接受方通过分析协议头分析本次通信有多少数据要接收，然后继续读后面的数据，直到一个封包被完整接收完才接收下一个封包。 </p>
		<p>当服务器一次仅做一个异步调用时，上述封包协议头的解决方案是很有效的。但是，如果要充分发挥 IOCP 服务器的潜力，肯定有多个未决的异步读操作等待数据的到来。这意味着，多个一步操作不能按顺序完成，未决读 I/O 返回的字节流不能按顺序处理，接收到的字节流可能组合成正确的封包，也有可能组合成错误的封包。因此，要解决这个问题，还必须为提交的读 I/O 分配序列号。 </p>
		<p>  </p>
		<p>说明： </p>
		<p>本文主要译自《 Network programming for microsoft windows 》一书的 6.2 节《可伸缩的服务器体系结构》和 6.3 节《资源管理》。 </p>
		<p>其中包重新排序问题，参考 王艳平著 《 Windows 网络与通信程序设计 》 4.3.4 节《包重新排序问题》 。 </p><img src ="http://www.cppblog.com/lapcca/aggbug/133421.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2010-11-12 14:04 <a href="http://www.cppblog.com/lapcca/archive/2010/11/12/133421.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CVC内部杂志</title><link>http://www.cppblog.com/lapcca/archive/2010/11/11/133297.html</link><dc:creator>阿π</dc:creator><author>阿π</author><pubDate>Thu, 11 Nov 2010 04:44:00 GMT</pubDate><guid>http://www.cppblog.com/lapcca/archive/2010/11/11/133297.html</guid><wfw:comment>http://www.cppblog.com/lapcca/comments/133297.html</wfw:comment><comments>http://www.cppblog.com/lapcca/archive/2010/11/11/133297.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lapcca/comments/commentRss/133297.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lapcca/services/trackbacks/133297.html</trackback:ping><description><![CDATA[<p>
				<strong>
						<font color="#0000ff">CVC简介</font>
				</strong>
				<br />    Chinese VXER Community(中国毒客公社)，由一群毒客与计算机技术爱好者组成的组织。我们的目的是<br />揭示隐藏在病毒之后的秘密，研究病毒技术，跟踪病毒和反病毒发展的最新动态。<br /><br /><font color="blue" font="3"><b>成员名单</b></font>(括号内为加入时间):<br /><br />  <font color="blue"><b>GroupA：3 人</b></font><br />VanCheer(020820)          e4gle(020821)              Whg(030323)<br /><br />  <font color="blue"><b>GroupB：13 人</b></font><br />JACKHY(020820)       VXK(020821)       Longge(020821)          Hume(020821) <br />vBin(020821)         whale(020821)     guojpeng(020823)        youth(020829)<br />pkxp(020905)         wowocockl(020928) luandao2000(030411)     haiwei(030501)<br />风般的男人(030731)<br /><br /><font color="blue"><b>宗旨：</b></font><br /><br />1.自由的病毒技术研究与发展<br />2.无界的技术交流与合作<br />3.核心技术的研究使中国的病毒技术达到一定高度，普及技术的发展使中国的VXer群体得到增强。<br /><br /><font color="blue"><b>成员要求：</b></font><br /><br />1.对病毒技术不懈的探索<br />2.对公社的热爱<br />3.维护公社的声誉，不得以公社名义发布恶意病毒（所有成员认可的具有特定目的的除外）。<br />如果有好的作品发布，须在作品内注明作者属于CVC。<br /><br /><font color="blue"><b>成员工作方式：</b></font><br /><br />    以个人研究和相互交流为主。若有好的想法或项目需要大家一起动手，大家可以一起共同完成。<br />大家有好的想法而又自己无力完成的，可以公布出来由大家合力完成。<br />    不对成员工作进行量上的要求，但希望有质的保证。如果成员半年都没有出一项成果（完整病毒，<br />有用的代码，文章），则公社要对该成员的合格度重新进行审慎的考核。<br />    本公社成员状况复杂，很多都有繁忙工作要做，所以如果因工作实在紧张，那么可以对其进行宽限。<br />无论如何，希望成员在可能的情况下多出成果。<br /><br /><font color="blue"><b>组织方式：</b></font><br /><br />民主＋自由＋自律<br /><br />    现已开始对申请成员实行考核制，考核小组由7人组成，投票决定。成员申请需提交自己相应作品,成员<br />通过审核后给予相应权限，便于内部交流。<br />    <a href="http://www.logincom.com/member" target="_blank"><font color="#ff0000">我要申请成为成员</font></a><br /><br /><font color="blue"><b>有关说明:</b></font><br /><br />    我们希望CVC的成员个个是中国毒坛的精华，GA成员更应该是中国的一流VXer，也更应该付出巨大<br />的努力。我们的成员不是加入就可以了，要出成绩，还是有很大压力的。尤其是GA，我们更要严格要求，<br />一旦发现不合适，坚决撤销身份，绝不留情，请大家能明白，到时不要有怨言。肯加入GA，就要有承受<br />压力的心理准备，就要有出成绩的决心，否则还是不要加入的好。 <br />    计划GA的成员数控制在5－6人，最多不超过10人，所以我们要仔细遴选，我们也不会讲人情，我们<br />要的是技术。 <br />    本公社是一个长期的组织，也需要大家长期的努力和支持。 <br /><br /><br /><br /><br /><a href="/Files/lapcca/cvc_issue1.zip">下载</a></p><img src ="http://www.cppblog.com/lapcca/aggbug/133297.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lapcca/" target="_blank">阿π</a> 2010-11-11 12:44 <a href="http://www.cppblog.com/lapcca/archive/2010/11/11/133297.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>