??xml version="1.0" encoding="utf-8" standalone="yes"?>久久久久女人精品毛片,亚洲人成无码www久久久,久久精品无码专区免费青青 http://www.shnenglu.com/Lee7/category/4849.html 当华的叶片落尽Q生命的脉络才历历可见?Q- 聂鲁? zh-cnSun, 14 Jun 2009 08:50:21 GMTSun, 14 Jun 2009 08:50:21 GMT60C/C++中Static的作用详q?/title><link>http://www.shnenglu.com/Lee7/archive/2009/03/01/75263.html</link><dc:creator>isabc</dc:creator><author>isabc</author><pubDate>Sun, 01 Mar 2009 14:07:00 GMT</pubDate><guid>http://www.shnenglu.com/Lee7/archive/2009/03/01/75263.html</guid><wfw:comment>http://www.shnenglu.com/Lee7/comments/75263.html</wfw:comment><comments>http://www.shnenglu.com/Lee7/archive/2009/03/01/75263.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/Lee7/comments/commentRss/75263.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Lee7/services/trackbacks/75263.html</trackback:ping><description><![CDATA[     摘要: 首先static的最主要功能是隐藏,其次因ؓstatic变量存放在静态存储区Q所以它具备持久性和默认?.  <a href='http://www.shnenglu.com/Lee7/archive/2009/03/01/75263.html'>阅读全文</a><img src ="http://www.shnenglu.com/Lee7/aggbug/75263.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Lee7/" target="_blank">isabc</a> 2009-03-01 22:07 <a href="http://www.shnenglu.com/Lee7/archive/2009/03/01/75263.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>变长l构?/title><link>http://www.shnenglu.com/Lee7/archive/2009/02/19/74340.html</link><dc:creator>isabc</dc:creator><author>isabc</author><pubDate>Thu, 19 Feb 2009 14:50:00 GMT</pubDate><guid>http://www.shnenglu.com/Lee7/archive/2009/02/19/74340.html</guid><wfw:comment>http://www.shnenglu.com/Lee7/comments/74340.html</wfw:comment><comments>http://www.shnenglu.com/Lee7/archive/2009/02/19/74340.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.shnenglu.com/Lee7/comments/commentRss/74340.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Lee7/services/trackbacks/74340.html</trackback:ping><description><![CDATA[     摘要:   <a href='http://www.shnenglu.com/Lee7/archive/2009/02/19/74340.html'>阅读全文</a><img src ="http://www.shnenglu.com/Lee7/aggbug/74340.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Lee7/" target="_blank">isabc</a> 2009-02-19 22:50 <a href="http://www.shnenglu.com/Lee7/archive/2009/02/19/74340.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>BOOL和bool的区?/title><link>http://www.shnenglu.com/Lee7/archive/2008/12/14/69394.html</link><dc:creator>isabc</dc:creator><author>isabc</author><pubDate>Sun, 14 Dec 2008 04:28:00 GMT</pubDate><guid>http://www.shnenglu.com/Lee7/archive/2008/12/14/69394.html</guid><wfw:comment>http://www.shnenglu.com/Lee7/comments/69394.html</wfw:comment><comments>http://www.shnenglu.com/Lee7/archive/2008/12/14/69394.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Lee7/comments/commentRss/69394.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Lee7/services/trackbacks/69394.html</trackback:ping><description><![CDATA[一?<br>1、类型不?<br>BOOL为int?<br>bool为布型 <br>2、长度不?<br>bool只有一个字?<br>BOOL长度视实际环境来定,一般可认ؓ?个字?<br>3、取g?<br>bool取值false和trueQ是0?的区?<br>BOOL取值FALSE和TRUEQ是0和非0的区?<br>二: <br>bool是标准C++数据cdQ可取值true和false。单独占一个字节, <br>如果Cbool对象列在一P可能会各占一个bitQ这取决于编译器?<br><br>BOOL是微软定义的typedef int BOOL。与bool不同Q它是一个三值逻辑Q?<br>TRUE/FALSE/ERRORQ返回gؓ>0的整CؓTRUEQ?为FALSEQ?1为ERROR?<br>Win32 API中很多返回gؓBOOL的函数都是三值逻辑。比如GetMessage(). <br>三: <br>大BOOL和小bool之间的区别: <br>1、类型不?<br>BOOL为int?<br>bool为布型 <br>2、长度不?<br>bool只有一个字?<br>BOOL长度视实际环境来定,一般可认ؓ?个字?<br>3、取g?<br>bool取值false和trueQ是0?的区?<br>BOOL取值FALSE和TRUEQ是0和非0的区?<br>4、例?<br>bool x=3;  //告警 <br>bool x=1;  //正确 <br>BOOL x=3;  //正确 <br>BOOL x=3.3;  //告警 <br>注:windowsZ兼容问题定义的基变量?<br>typedef unsigned long        DWORD; <br>typedef int                  BOOL; <br>typedef unsigned char        BYTE; <br>typedef unsigned short      WORD; <br>typedef float                FLOAT; <br>typedef FLOAT                *PFLOAT; <br>typedef BOOL near            *PBOOL; <br>typedef BOOL far            *LPBOOL; <br>typedef BYTE near            *PBYTE; <br>typedef BYTE far            *LPBYTE; <br>typedef int near            *PINT; <br>typedef int far              *LPINT; <img src ="http://www.shnenglu.com/Lee7/aggbug/69394.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Lee7/" target="_blank">isabc</a> 2008-12-14 12:28 <a href="http://www.shnenglu.com/Lee7/archive/2008/12/14/69394.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>数据l构复习W记http://www.shnenglu.com/Lee7/archive/2008/11/24/67741.htmlisabcisabcMon, 24 Nov 2008 08:44:00 GMThttp://www.shnenglu.com/Lee7/archive/2008/11/24/67741.htmlhttp://www.shnenglu.com/Lee7/comments/67741.htmlhttp://www.shnenglu.com/Lee7/archive/2008/11/24/67741.html#Feedback8http://www.shnenglu.com/Lee7/comments/commentRss/67741.htmlhttp://www.shnenglu.com/Lee7/services/trackbacks/67741.html阅读全文

isabc 2008-11-24 16:44 发表评论
]]>
堆和栈的区别在哪里? http://www.shnenglu.com/Lee7/archive/2008/11/14/66925.htmlisabcisabcFri, 14 Nov 2008 08:12:00 GMThttp://www.shnenglu.com/Lee7/archive/2008/11/14/66925.htmlhttp://www.shnenglu.com/Lee7/comments/66925.htmlhttp://www.shnenglu.com/Lee7/archive/2008/11/14/66925.html#Feedback0http://www.shnenglu.com/Lee7/comments/commentRss/66925.htmlhttp://www.shnenglu.com/Lee7/services/trackbacks/66925.html堆和?/span>的区别在哪里Q?/span>      
     
 
哪些变量会在栈中分配I间Q哪些变量会在堆中分配空?/span>?      
  ---------------------------------------------------------------      
  1
?span style="COLOR: maroon">甌方式
         
  stack:          
 
ql?span style="COLOR: red">自动分配?/span>     例如Q声明在函数中一个局部变?/span>     int     b;     pȝ自动在栈中ؓb开辟空?/span>          
  heap:          
 
需要程序员自己甌Qƈ指明大小Q在c?/span>malloc函数          
 
?/span>p1 = (char *)malloc(10);     //free     
 
?/span>C++中用newq算W?/span>           //delete
 
?/span>p2 = (char *)malloc(10);          
 
但是注意p1?/span>p2本n是在栈中的?/span>          
     
  2
?span style="COLOR: maroon">甌后系l的响应
         
 
栈:只要栈的剩余I间大于所甌I间Q系l将为程序提供内存,否则报异常提示栈溢?/span>?/span>          
 
堆:首先应该知道操作pȝ有一?span style="COLOR: red">记录I闲内存地址的链?/span>Q当pȝ收到E序的申hQ?/span>          
 
会遍历该链表Q寻扄一个空间大于所甌I间的堆l点Q然后将该结点从I闲l点链表中删除,q将该结点的I间分配l程序,另外Q对于大多数pȝQ会在这块内存空间中的首地址处记录本ơ分配的大小Q这P代码中的delete语句才能正确的释放本内存I间。另外,׃扑ֈ的堆l点的大不一定正好等于申L大小Q系l会自动的将多余的那部分重新攑օI闲链表中?/span>          
     
  3
?span style="COLOR: maroon">甌大小的限?/span>          
 
栈:?/span>Windows?/span>,栈是向低地址扩展的数据结构,是一块连l的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是pȝ预先规定好的Q在WINDOWS下,栈的大小?/span>2MQ也有的说是1MQM是一个编译时q定的常数Q,如果甌的空间超q栈的剩余空间时Q将提示overflow。因此,能从栈获得的I间较小?/span>          
 
堆:堆是向高地址扩展的数据结构,是不q箋的内存区域。这是由于系l是用链表来存储的空闲内存地址的,自然是不q箋的,而链表的遍历方向是由低地址向高地址。堆的大受限于计算机系l中有效的虚拟内存。由此可见,堆获得的I间比较灉|Q也比较?/span>?/span>          
     
  4
?span style="COLOR: maroon">甌效率的比较:
         
 
栈由pȝ自动分配Q?span style="COLOR: red">速度较快。但E序员是无法控制的?/span>          
 
堆是?/span>new分配的内?/span>Q一?span style="COLOR: red">速度比较?/span>Q而且Ҏ产生内存片,不过用v来最方便.          
 
另外Q在WINDOWS下,最好的方式是用VirtualAlloc分配内存Q他不是在堆Q也不是在栈是直接在q程的地址I间中保留一快内存,虽然用v来最不方ѝ但是速度快,也最灉|?/span>          
     
  5
?span style="COLOR: maroon">堆和栈中的存储内?/span>          
 
栈:在函数调用时Q第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句Q的地址Q然后是函数的各个参敎ͼ在大多数?/span>C~译器中Q参数是由右往左入栈的Q然后是函数中的局部变量。注意静态变量是不入栈的?/span>          
 
当本ơ函数调用结束后Q局部变量先出栈Q然后是参数Q最后栈指针指向最开始存的地址Q也是dC的下一条指令,E序p点l运行?/span>          
 
堆:一般是在堆的头部用一个字节存攑֠的大。堆中的具体内容有程序员安排?/span>          
     
  6
?span style="COLOR: maroon">存取效率的比?/span>          
  char     s1[]     =     "aaaaaaaaaaaaaaa";          
  char     *s2     =     "bbbbbbbbbbbbbbbbb";          
  aaaaaaaaaaa
是在q行时刻赋值的Q?/span>          
 
?/span>bbbbbbbbbbb是在~译时就定的;          
 
但是Q在以后的存取中Q在栈上的数l比指针所指向的字W串(例如?/span>)快?/span>          
 
比如Q?/span>           

  #include           
  
void     main()           
  
{           
  
char     a     =     1;           
  
char     c[]     =     "1234567890";           
  
char     *p     ="1234567890";           
  a     
=     c[1];           
  a     
=     p[1];           
  
return;           
  }
  

         
  堆和栈的区别可以用如下的比喻来看出:          
 
使用栈就象我们去饭馆里吃饭,只管点菜Q发出申P、付钱、和吃(使用Q,吃饱了就赎ͼ不必理会切菜、洗菜等准备工作和洗、刷锅等扫尾工作Q他的好处是快捷Q但是自由度?/span>          
 



isabc 2008-11-14 16:12 发表评论
]]>
用static声明的函数和变量结[转]http://www.shnenglu.com/Lee7/archive/2008/11/14/66924.htmlisabcisabcFri, 14 Nov 2008 07:59:00 GMThttp://www.shnenglu.com/Lee7/archive/2008/11/14/66924.htmlhttp://www.shnenglu.com/Lee7/comments/66924.htmlhttp://www.shnenglu.com/Lee7/archive/2008/11/14/66924.html#Feedback0http://www.shnenglu.com/Lee7/comments/commentRss/66924.htmlhttp://www.shnenglu.com/Lee7/services/trackbacks/66924.html?/span>static声明的函数和变量结

static 声明的变量在C语言中有两方?/span>的特征:
  1)、变量会被放在程序的全局存储?/span>中,q样可以在下一ơ调用的时候还可以保持原来的赋?/span>。这一Ҏ它与堆栈变量和堆变量的区别?/span>
  2)、变量用static告知~译器,自己仅仅在变量的作用范围内可?/span>。这一Ҏ它与全局变量的区别?/span>
Tips:
  A.若全局变量仅在单个C文g中访问,则可以将q个变量修改为静态全局变量Q以降低模块间的耦合度;
  B.若全局变量仅由单个函数讉KQ则可以这个变量改函数的静态局部变量,以降低模块间的耦合度;
  C.设计和用访问动态全局变量、静态全局变量、静态局部变量的函数Ӟ需要考虑重入问题Q?/span>
        D.
如果我们需要一个可重入的函敎ͼ那么Q我们一定要避免函数中?/span>static变量(q样的函数被UCؓQ带内部存储?/span>功能的的函数)
        E.
函数中必要使用static变量情况:比如当某函数的返回gؓ指针cdӞ则必Lstatic的局部变量的地址作ؓq回|若ؓautocdQ则q回为错指针?/span>

函数前加static使得函数成ؓ静态函?/span>。但此处“static”的含?span style="COLOR: red">不是指存储方?/span>Q而是指对函数?span style="COLOR: red">作用域仅局限于本文?/span>(所以又U内部函?/span>)。用内部函数的好处是:不同的h~写不同的函数时Q不用担心自己定义的函数Q是否会与其它文件中的函数同名?/span>

扩展分析:术语static有着不寻常的历史.起初Q在C中引入关键字static是ؓ了表C退Z个块后仍然存在的局部变量。随后,static?/span>C中有了第二种含义Q用来表CZ能被其它文g讉K的全局变量和函数。ؓ了避免引入新的关键字Q所以仍使用static关键字来表示q第二种含义。最后,C++重用了这个关键字Qƈ赋予它与前面不同的第三种含义Q表C属于一个类而不是属于此cȝM特定对象的变量和函数(?/span>Java中此关键字的含义相同)?/span>

全局变量、静态全局变量、静态局部变量和局部变量的区别

变量可以分ؓQ全局变量、静态全局变量、静态局部变量和局部变量?/span>
         
?span style="COLOR: red">存储区域分,全局变量、静态全局变量和静态局部变量都存放在内存的静态存储区?/span>Q局部变量存攑֜内存?span style="COLOR: red">栈区?/span>
         
?span style="COLOR: red">作用?/span>分,全局变量在整个工E文件内都有效;静态全局变量只在定义它的文g内有效;静态局部变量只在定义它的函数内有效Q只是程序仅分配一ơ内存,函数q回后,该变量不会消失;局部变量在定义它的函数内有效,但是函数q回后失?/span>?/span>

全局变量(外部变量)的说明之前再冠以static 构成了静态的全局变量。全局变量本n是静态存储方式, 静态全局变量当然也是静态存储方式?/span> q两者在存储方式上ƈ无不同。这两者的区别虽在于非静态全局变量的作用域是整个源E序Q?/span> 当一个源E序由多个源文gl成Ӟ非静态的全局变量在各个源文g中都是有效的?/span> 而静态全局变量则限制了其作用域Q?/span> 卛_在定义该变量的源文g内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文g内,只能源文件内的函数公用, 因此可以避免在其它源文g中引起错误?/span>

  从以上分析可以看出, 把局部变量改变ؓ静态变量后是改变了它的存储方式x变了它的生存?/span>。把全局变量改变为静态变量后是改变了它的作用?/span>Q?/span> 限制了它的用范围?/span>

  static函数与普通函C用域不同?span style="COLOR: red">仅在本文件。只在当前源文g中用的函数应该说明为内部函?/span>(static)Q内部函数应该在当前源文件中说明和定义。对于可在当前源文g以外使用的函敎ͼ应该在一个头文g中说明,要用这些函数的源文件要包含q个头文?/span>

  static全局变量与普通的全局变量有什么区别:static全局变量只初始化一ơ,防止在其他文件单元中被引?/span>;
  static局部变量和普通局部变量有什么区别:static局部变量只被初始化一ơ,下一ơ依据上一ơ结果|
       static
函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中l持一份拷?/span>
       
全局变量和静态变量如果没有手工初始化Q?span style="COLOR: red">则由~译器初始化?/span>0。局部变量的g可知?/span>

 

 



isabc 2008-11-14 15:59 发表评论
]]>
vc数据cd转换大全http://www.shnenglu.com/Lee7/archive/2008/10/23/64807.htmlisabcisabcThu, 23 Oct 2008 06:27:00 GMThttp://www.shnenglu.com/Lee7/archive/2008/10/23/64807.htmlhttp://www.shnenglu.com/Lee7/comments/64807.htmlhttp://www.shnenglu.com/Lee7/archive/2008/10/23/64807.html#Feedback0http://www.shnenglu.com/Lee7/comments/commentRss/64807.htmlhttp://www.shnenglu.com/Lee7/services/trackbacks/64807.html阅读全文

isabc 2008-10-23 14:27 发表评论
]]>
More Effective C++Q指针与引用的区?/title><link>http://www.shnenglu.com/Lee7/archive/2008/09/02/60717.html</link><dc:creator>isabc</dc:creator><author>isabc</author><pubDate>Tue, 02 Sep 2008 09:35:00 GMT</pubDate><guid>http://www.shnenglu.com/Lee7/archive/2008/09/02/60717.html</guid><wfw:comment>http://www.shnenglu.com/Lee7/comments/60717.html</wfw:comment><comments>http://www.shnenglu.com/Lee7/archive/2008/09/02/60717.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Lee7/comments/commentRss/60717.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Lee7/services/trackbacks/60717.html</trackback:ping><description><![CDATA[     摘要: 指针与引用看上去完全不同Q指针用操作W?’和?>’,引用使用操作W?’)Q但是它们似乎有相同的功能。指针与引用都是让你间接引用其他对象。你如何军_在什么时候用指针,在什么时候用引用呢Q?<br>  <a href='http://www.shnenglu.com/Lee7/archive/2008/09/02/60717.html'>阅读全文</a><img src ="http://www.shnenglu.com/Lee7/aggbug/60717.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Lee7/" target="_blank">isabc</a> 2008-09-02 17:35 <a href="http://www.shnenglu.com/Lee7/archive/2008/09/02/60717.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>堆、栈及静态数据区详解 http://www.shnenglu.com/Lee7/archive/2008/08/31/60530.htmlisabcisabcSun, 31 Aug 2008 13:43:00 GMThttp://www.shnenglu.com/Lee7/archive/2008/08/31/60530.htmlhttp://www.shnenglu.com/Lee7/comments/60530.htmlhttp://www.shnenglu.com/Lee7/archive/2008/08/31/60530.html#Feedback0http://www.shnenglu.com/Lee7/comments/commentRss/60530.htmlhttp://www.shnenglu.com/Lee7/services/trackbacks/60530.html阅读全文

isabc 2008-08-31 21:43 发表评论
]]>
DllMain详解http://www.shnenglu.com/Lee7/archive/2008/08/04/57927.htmlisabcisabcMon, 04 Aug 2008 01:26:00 GMThttp://www.shnenglu.com/Lee7/archive/2008/08/04/57927.htmlhttp://www.shnenglu.com/Lee7/comments/57927.htmlhttp://www.shnenglu.com/Lee7/archive/2008/08/04/57927.html#Feedback0http://www.shnenglu.com/Lee7/comments/commentRss/57927.htmlhttp://www.shnenglu.com/Lee7/services/trackbacks/57927.htmlThe DllMain function is an optional method of entry into a dynamic-link library (DLL)。(要翻译:对于一个Dll模块QDllMain函数是可选的。)q句话很重要Q很多初学者可能都认ؓ一个动态链接库肯定要有DllMain函数。其实不Ӟ像很多仅仅包含资源信息的DLL是没有DllMain函数?nbsp; 阅读全文

isabc 2008-08-04 09:26 发表评论
]]>
VC++动态链接库(DLL)~程深入出http://www.shnenglu.com/Lee7/archive/2008/07/07/55543.htmlisabcisabcMon, 07 Jul 2008 07:39:00 GMThttp://www.shnenglu.com/Lee7/archive/2008/07/07/55543.htmlhttp://www.shnenglu.com/Lee7/comments/55543.htmlhttp://www.shnenglu.com/Lee7/archive/2008/07/07/55543.html#Feedback0http://www.shnenglu.com/Lee7/comments/commentRss/55543.htmlhttp://www.shnenglu.com/Lee7/services/trackbacks/55543.html 静态链接库与动态链接库都是׃n代码的方式,如果采用静态链接库Q则无论你愿不愿意,lib中的指o都被直接包含在最l生成的EXE文g中了。但是若使用DLLQ该DLL不必被包含在最lEXE文g中,EXE文g执行时可以“动态”地引用和卸载这个与EXE独立的DLL文g。静态链接库和动态链接库的另外一个区别在于静态链接库中不能再包含其他的动态链接库或者静态库Q而在动态链接库中还可以再包含其他的动态或静态链接库?nbsp; 阅读全文

isabc 2008-07-07 15:39 发表评论
]]>
vc dll~程http://www.shnenglu.com/Lee7/archive/2008/07/04/55361.htmlisabcisabcFri, 04 Jul 2008 09:54:00 GMThttp://www.shnenglu.com/Lee7/archive/2008/07/04/55361.htmlhttp://www.shnenglu.com/Lee7/comments/55361.htmlhttp://www.shnenglu.com/Lee7/archive/2008/07/04/55361.html#Feedback0http://www.shnenglu.com/Lee7/comments/commentRss/55361.htmlhttp://www.shnenglu.com/Lee7/services/trackbacks/55361.html1.Non-MFC Dlls
2.Regular Dlls
3.Extension Dlls Note:译措辞不当Q故遇到术语是引用原?

Non-MFC DLL:指的是不用MFC的类库结构,直接用C语言写的DLLQ其输出的函C般用的是标准C接口Qƈ能被非MFC或MFC~写的应用程序所调用。LLQRegular DLL:和下q的Extension Dlls一P是用MFCcd~写的。明昄特点是在源文仉有一个承CWinApp的类。其又可l分成静态连接到MFC和动态连接到MFC上的。但静态连接到MFC的动态连  阅读全文

isabc 2008-07-04 17:54 发表评论
]]>
VC之DLL~程http://www.shnenglu.com/Lee7/archive/2008/06/20/54127.htmlisabcisabcFri, 20 Jun 2008 06:07:00 GMThttp://www.shnenglu.com/Lee7/archive/2008/06/20/54127.htmlhttp://www.shnenglu.com/Lee7/comments/54127.htmlhttp://www.shnenglu.com/Lee7/archive/2008/06/20/54127.html#Feedback0http://www.shnenglu.com/Lee7/comments/commentRss/54127.htmlhttp://www.shnenglu.com/Lee7/services/trackbacks/54127.html
动态连接库Q多个应用程序可以共享一份函数库的备份?
  阅读全文

isabc 2008-06-20 14:07 发表评论
]]>
CFileFindcȝ使用ȝ[转]http://www.shnenglu.com/Lee7/archive/2008/05/27/51295.htmlisabcisabcTue, 27 May 2008 09:05:00 GMThttp://www.shnenglu.com/Lee7/archive/2008/05/27/51295.htmlhttp://www.shnenglu.com/Lee7/comments/51295.htmlhttp://www.shnenglu.com/Lee7/archive/2008/05/27/51295.html#Feedback0http://www.shnenglu.com/Lee7/comments/commentRss/51295.htmlhttp://www.shnenglu.com/Lee7/services/trackbacks/51295.htmlCFileFindcȝ使用ȝ
2007-7-7
1?/span>CFileFindcȝ声明文g保存?/span>afx.h头文件中?/span>
2、该cȝ实现的功能:执行本地文g的查?/span>(查找某个具体的文Ӟ查找某类文gx*.x*Q查找所有文?/span>*.*)
3?/span>CFileFindcLCGopherFileFind?/span>CFtpFileFindcȝ基类?/span>
4?/span>CFileFindcȝ构造函?/span>::CFileFind()和关闭函?/span>::Close()我会成对使用?/span>
5?/span>CFileFindcȝ成员函数我根据其操作Ҏ划分ؓQ类Q查找操作类、获得文件属性类、判断文件属性类?/span>(下面我先q行函数|列q没有完整的描述函数的参?/span>)
查找操作c?/span>
      ::FindFile();
      ::FindNextFile();
获得文g属性类
      ::GetCreationTime();
      ::GetLastAccessTime();
      ::GetLastWriteTime();
::GetFileName();
::GetRoot();
      ::GetFilePath();
      ::GetFileTitle();
      ::GetFileURL();
      ::GetLength();
     
判断文g属性类
      ::IsArchived();
      ::IsCompressed();
      ::IsDirectory();
      ::IsDots();
      ::IsHidden();
      ::IsNormal();
      ::IsReadOnly();
      ::IsSystem();
      ::IsTemporary();
      ::MatchesMask();
6?/span>CFileFindcM成员函数使用应注意的序
      在创ZCFileFind对象后,先执?/span>::FindFile()函数Q然后执?/span>::FindNextFile()Q然后选择执行Q获得文件属性类Q的函数或者(判断文g属性类Q函数?/span>
7?/span>CFileFindcL员函数的详细分析
virtual BOOL FindFile(LPCTSTR pstrName = null,DWORD dwUnused = 0);
该函数若q回?/span>0 则表明执行成功,0 则表明执行不成功?/span>
pstrNameQ需要查扄文g名,例:“E:\\~程工具\\VC++\\MFC例子.rar”Q?#8220;E:\\~程工具\\VC++\\MFC*.rar”Q?#8220;E:\\~程工具\\VC++\\*.*”Q也可以?/span>NULL表示“*.*”?/span>
dwUnusedQ必Mؓ0
 
virtual BOOL FindNextFile();
该函数返回?/span>?/span>0 q有W合条g的文?/span>Q?/span> 0表示是最后一个文件?/span>
 
virtual BOOL GetCreationTime(FILETIME *pFileTime) const;
virtual BOOL GetCreationTime(CTime& refTime) const;
该函数用来获得查扑ֈ的某个文件的创徏旉Q返回?/span>?/span>0 获得创徏旉成功操作Q?/span>0表示执行获得创徏旉p|或?/span>FindNextFile()没有被执行的时候?/span>
FILETIME  *Q容Ux间的l构指针
CTime&Q容Ux间的对象地址
此处介绍Q?/span>FILETIME?/span>CTime怺转换的处理方法:
FILETIME?/span>CTime的方法:
A?/span>CTime对象在初始化时可以传?/span>FILETIMEl构
      FILETIME ftQ?/span>
      CTime time(ft)Q?/span>
B、将FILETIME转换?/span>SYSTEMTIMEQ然?/span>CTime对象在初始化时可以传?/span>SYSTEMTIMEl构
      FILETIME ftQ?/span>
      SYSTEMTIME stQ?/span>
      BOOL bSuccess Q?/span> ::FileTimeToSystemTime(&ft , &st);
      CTime time(st)Q?/span>
CTime?/span>FILETIMEҎQ?/span>
CTime time(CTime::GetCurrentTime());
SYSTEMTIME st;
time.GetAsSystemTime(st);
FILETIME ft;
::SystemTimeToFileTime(&st,&ft);
 
virtual BOOL GetLastAccessTime(FILETIME *pFileTime) const;
virtual BOOL GetLastAccessTime(CTime& refTime) const;
该函数用来获得某个文件最后被讉K的时_?/span>0表示执行成功Q?/span>0表示执行p|或?/span>FindNextFile()函数没有执行的时候?/span>
 
virtual BOOL GetLastWriteTime(FILETIME *pFileTime) const;
virtual BOOL GetLastWriteTime(CTime& refTime) const;
该函数用来获得某个文件最后被讉K的时_?/span>0表示执行成功Q?/span>0表示执行p|或?/span>FindNextFile()函数没有执行的时候?/span>
 
virtual CString GetFilePath() const;
该函数用来获得查扑ֈ的文件绝对\径,必须在执行了FindNextFile()后该函数才能执行成功?/span>
q回的结果是CString对象Q例“E:\\~程工具\\VC++\\MFC.rar
 
virtual CString GetFileName() const;
该函数用来获得查扑ֈ的文件的全称Q必d执行?/span>FindNextFile()后该函数才能执行成功?/span>
q回的结果是CString对象Q例“MFC.rar
 
virtual CString GetFileTitle() const;
该函数用来获得查扑ֈ的文件的名称Q必d执行?/span>FindNextFile()后该函数才能执行成功?/span>
q回的结果是CString对象Q例“MFC
 
virtual CString GetRoot() const;
该函数用来获得查扑ֈ的文件的根目录,必须在执行了FindNextFile()后该函数才能执行成功?/span>
q回的结果是CString对象Q例“E:\\~程工具\\VC++\\
 
virtual CString GetFileURL() const;
该函数用来获得查扑ֈ的文件的URL路径Q必d执行?/span>FindNextFile()后该函数才能执行成功?/span>
q回的结果是CString对象Q例“file://E:\\~程工具\\VC++\\MFC.rar
 
DWORD GetLength() const;
该函数返回D得查扑ֈ的文件的长度Q必d执行?/span>FindNextFile()后该函数才能执行成功?/span>
 
BOOL IsArchived() const;
该函数用来判断查扄文g属性是否是档案文gQ非0表示是,0表示不是。必d执行?/span>FindNextFile()后该函数才能执行成功
 
BOOL  IsCompressed() const;
该函数用来判断查扄文g属性是否是压羃文gQ非0表示是,0表示不是。必d执行?/span>FindNextFile()后该函数才能执行成功
 
BOOL IsDirectory() const;
该函数用来判断查扄文g属性是否是路径文gQ非0表示是,0表示不是。必d执行?/span>FindNextFile()后该函数才能执行成功
 
BOOL IsDots() const;
该函数用来判断查扄文g属性是否是“.”Q?#8220;..”Q非0表示是,0表示不是。必d执行?/span>FindNextFile()后该函数才能执行成功
 
BOOL IsHidden() const;
该函数用来判断查扄文g属性是否隐藏文Ӟ?/span>0表示是,0表示不是。必d执行?/span>FindNextFile()后该函数才能执行成功
 
BOOL IsNormal() const;
该函数用来判断查扄文g属性是否正常文Ӟ?/span>0表示是,0表示不是。必d执行?/span>FindNextFile()后该函数才能执行成功
 
BOOL IsReadOnly() const;
该函数用来判断查扄文g属性是否只LӞ?/span>0表示是,0表示不是。必d执行?/span>FindNextFile()后该函数才能执行成功
 
BOOL IsSystem() const;
该函数用来判断查扄文g属性是否系l文Ӟ?/span>0表示是,0表示不是。必d执行?/span>FindNextFile()后该函数才能执行成功
 
BOOL IsTemporary() const;
该函数用来判断查扄文g属性是否时文Ӟ?/span>0表示是,0表示不是。必d执行?/span>FindNextFile()后该函数才能执行成功
 
BOOL MatchesMask(DWORD dwMask) const;
该函数用来判断查扄文g的综合属性,?/span>0表示是,0表示不是。必d执行?/span>FindNextFile()后该函数才能执行成功
dwMask参数的用方法:几种文g属性采用或q算Q?/span>|Q?/span>
文g属性的l构定义Q?/span>
      FILE_ATTRIBUTE_ARCHIVEQ案文?/span>
      FILE_ATTRIBUTE_COMPRESSEDQ压~文?/span>
      FILE_ATTRIBUTE_DIRECTORYQ\径文?/span>
      FILE_ATTRIBUTE_NORMALQ正常文?/span>
      FILE_ATTRIBUTE_READONLYQ只L?/span>
      FILE_ATTRIBUTE_SYSTEMQ系l文?/span>
      FILE_ATTRIBUTE_TEMPORARYQ时文?/span>
      FILE_ATTRIBUTE_HIDDENQ隐藏文?/span>
 


isabc 2008-05-27 17:05 发表评论
]]>
你会用sizeof吗?Qvc)http://www.shnenglu.com/Lee7/archive/2008/05/25/51077.htmlisabcisabcSun, 25 May 2008 13:55:00 GMThttp://www.shnenglu.com/Lee7/archive/2008/05/25/51077.htmlhttp://www.shnenglu.com/Lee7/comments/51077.htmlhttp://www.shnenglu.com/Lee7/archive/2008/05/25/51077.html#Feedback1http://www.shnenglu.com/Lee7/comments/commentRss/51077.htmlhttp://www.shnenglu.com/Lee7/services/trackbacks/51077.html

你会用sizeof吗?Qvc)

 
本文主要包括二个部分Q第一部分重点介绍在VC中,怎么样采用sizeof来求l构的大,以及Ҏ出现的问题,q给决问题的ҎQ第二部分ȝ出VC中sizeof的主要用法?br>
1?sizeof应用在结构上的情?br>
L下面的结构:

struct MyStruct

{

double dda1;

char dda;

int type

};

对结构MyStruct采用sizeof会出C么结果呢Qsizeof(MyStruct)为多呢Q也怽会这hQ?br>
sizeof(MyStruct)=sizeof(double)+sizeof(char)+sizeof(int)=13

但是当在VC中测试上面结构的大小Ӟ你会发现sizeof(MyStruct)?6。你知道Z么在VC中会得出q样一个结果吗Q?br>
其实Q这是VC对变量存储的一个特D处理。ؓ了提高CPU的存储速度QVC对一些变量的起始地址做了“寚w”处理。在默认情况下,VC规定各成员变量存攄起始地址相对于结构的起始地址的偏U量必须变量的类型所占用的字节数的倍数。下面列出常用类型的寚w方式(vc6.0,32位系l??br>
cd
寚w方式Q变量存攄起始地址相对于结构的起始地址的偏U量Q?br>
Char
偏移量必Mؓsizeof(char)?的倍数

int
偏移量必Mؓsizeof(int)?的倍数

float
偏移量必Mؓsizeof(float)?的倍数

double
偏移量必Mؓsizeof(double)?的倍数

Short
偏移量必Mؓsizeof(short)?的倍数



各成员变量在存放的时候根据在l构中出现的序依次甌I间Q同时按照上面的寚w方式调整位置Q空~的字节VC会自动填充。同时VCZ保l构的大ؓl构的字节边界数Q即该结构中占用最大空间的cd所占用的字节数Q的倍数Q所以在为最后一个成员变量申L间后Q还会根据需要自动填充空~的字节?br>
下面用前面的例子来说明VC到底怎么h存放l构的?br>
struct MyStruct

{

double dda1;

char dda;

int type

}Q?br>
Z面的l构分配I间的时候,VCҎ成员变量出现的顺序和寚w方式Q先为第一个成员dda1分配I间Q其起始地址跟结构的起始地址相同Q刚好偏U量0刚好为sizeof(double)的倍数Q,该成员变量占用sizeof(double)=8个字节;接下来ؓW二个成员dda分配I间Q这时下一个可以分配的地址对于l构的v始地址的偏U量?Q是sizeof(char)的倍数Q所以把dda存放在偏U量?的地Ҏ_齐方式,该成员变量占用sizeof(char)=1个字节;接下来ؓW三个成员type分配I间Q这时下一个可以分配的地址对于l构的v始地址的偏U量?Q不是sizeof(int)=4的倍数Qؓ了满_齐方式对偏移量的U束问题QVC自动填充3个字节(q三个字节没有放什么东西)Q这时下一个可以分配的地址对于l构的v始地址的偏U量?2Q刚好是sizeof(int)=4的倍数Q所以把type存放在偏U量?2的地方,该成员变量占用sizeof(int)=4个字节;q时整个l构的成员变量已l都分配了空_ȝ占用的空间大ؓQ?+1+3+4=16Q刚好ؓl构的字节边界数Q即l构中占用最大空间的cd所占用的字节数sizeof(double)=8Q的倍数Q所以没有空~的字节需要填充。所以整个结构的大小为:sizeof(MyStruct)=8+1+3+4=16Q其中有3个字节是VC自动填充的,没有放Q何有意义的东ѝ?br>
下面再D个例子,交换一下上面的MyStruct的成员变量的位置Q它变成下面的情况Q?br>
struct MyStruct

{

char dda;

double dda1;

int type

}Q?br>
q个l构占用的空间ؓ多大呢?在VC6.0环境下,可以得到sizeof(MyStruc)?4。结合上面提到的分配I间的一些原则,分析下VC怎么样ؓ上面的结构分配空间的。(单说明)

struct MyStruct

{

char dda;//偏移量ؓ0Q满_齐方式,dda占用1个字节;

double dda1;//下一个可用的地址的偏U量?Q不是sizeof(double)=8

//的倍数Q需要补?个字节才能偏移量变?Q满_?br>
//方式Q,因此VC自动填充7个字节,dda1存放在偏U量?

//的地址上,它占?个字节?br>
int typeQ?/下一个可用的地址的偏U量?6Q是sizeof(int)=4的?br>
//敎ͼ满int的对齐方式,所以不需要VC自动填充Qtype?br>
//攑֜偏移量ؓ16的地址上,它占?个字节?br>
}Q?/所有成员变量都分配了空_I间ȝ大小?+7+8+4=20Q不是结?br>
//的节边界敎ͼ即结构中占用最大空间的cd所占用的字节数sizeof

//(double)=8Q的倍数Q所以需要填?个字节,以满结构的大小?br>
//sizeof(double)=8的倍数?br>


所以该l构ȝ大小为:sizeof(MyStruc)?+7+8+4+4=24。其中ȝ?+4=11个字节是VC自动填充的,没有放Q何有意义的东ѝ?br>


VC对结构的存储的特D处理确实提高CPU存储变量的速度Q但是有时候也带来了一些麻烦,我们也屏蔽掉变量默认的对齐方式,自己可以讑֮变量的对齐方式?br>
VC中提供了#pragma pack(n)来设定变量以n字节寚w方式。n字节寚w是说变量存攄起始地址的偏U量有两U情况:W一、如果n大于{于该变量所占用的字节数Q那么偏U量必须满默认的对齐方式,W二、如果n于该变量的cd所占用的字节数Q那么偏U量为n的倍数Q不用满默认的寚w方式。结构的d也有个U束条gQ分下面两种情况Q如果n大于所有成员变量类型所占用的字节数Q那么结构的d必Mؓ占用I间最大的变量占用的空间数的倍数Q?br>
否则必须为n的倍数。下面D例说明其用法?br>
#pragma pack(push) //保存寚w状?br>
#pragma pack(4)//讑֮?字节寚w

struct test

{

char m1;

double m4;

int m3;

};

#pragma pack(pop)//恢复寚w状?br>
以上l构的大ؓ16Q下面分析其存储情况Q首先ؓm1分配I间Q其偏移量ؓ0Q满x们自p定的寚w方式Q?字节寚wQ,m1占用1个字节。接着开始ؓm4分配I间Q这时其偏移量ؓ1Q需要补?个字节,q样使偏U量满为n=4的倍数Q因为sizeof(double)大于nQ?m4占用8个字节。接着为m3分配I间Q这时其偏移量ؓ12Q满ؓ4的倍数Qm3占用4个字节。这时已lؓ所有成员变量分配了I间Q共分配?6个字节,满为n的倍数。如果把上面?pragma pack(4)改ؓ#pragma pack(16)Q那么我们可以得到结构的大小?4。(误者自己分析)

2?sizeof用法ȝ

在VC中,sizeof有着许多的用法,而且很容易引起一些错误。下面根据sizeof后面的参数对sizeof的用法做个ȝ?br>
AQ?参数为数据类型或者ؓ一般变量。例如sizeof(int),sizeof(long){等。这U情况要注意的是不同pȝpȝ或者不同编译器得到的结果可能是不同的。例如intcd?6位系l中?个字节,?2位系l中?个字节?br>
BQ?参数为数l或指针。下面D例说?

int a[50]; //sizeof(a)=4*50=200; 求数l所占的I间大小

int *a=new int[50];// sizeof(a)=4; aZ个指针,sizeof(a)是求指针

//的大??2位系l中Q当然是?个字节?br>
CQ?参数为结构或cRSizeof应用在类和结构的处理情况是相同的。但有两炚w要注意,W一、结构或者类中的静态成员不对结构或者类的大生媄响,因ؓ静态变量的存储位置与结构或者类的实例地址无关?br>
W二、没有成员变量的l构或类的大ؓ1Q因为必M证结构或cȝ每一

个实例在内存中都有唯一的地址?br>
下面举例说明Q?br>
Class Test{int a;static double c};//sizeof(Test)=4.

Test *s;//sizeof(s)=4,sZ个指针?br>
Class test1{ };//sizeof(test1)=1;

DQ?参数为其他。下面D例说明?br>
int func(char s[5]);

{

cout<
//数的参数在传递的时候系l处理ؓ一个指针,所

//以sizeof(s)实际上ؓ求指针的大小?br>
return 1;

}

sizeof(func(“1234”))=4//因ؓfunc的返回类型ؓintQ所以相当于

//求sizeof(int).



以上为sizeof的基本用法,在实际的使用中要注意分析VC的分配变量的分配{略Q这L话可以避免一些错误?/td>


isabc 2008-05-25 21:55 发表评论
]]>
C++中的寸[转]http://www.shnenglu.com/Lee7/archive/2008/05/25/51076.htmlisabcisabcSun, 25 May 2008 13:53:00 GMThttp://www.shnenglu.com/Lee7/archive/2008/05/25/51076.htmlhttp://www.shnenglu.com/Lee7/comments/51076.htmlhttp://www.shnenglu.com/Lee7/archive/2008/05/25/51076.html#Feedback0http://www.shnenglu.com/Lee7/comments/commentRss/51076.htmlhttp://www.shnenglu.com/Lee7/services/trackbacks/51076.html转自Q?a >http://blog.csdn.net/arong1234/archive/2008/03/23/2210462.aspx

1. sizeof:q回cd的尺?/h3>

 每个cd在编译时都会军_自己的实例需要多字节。在~译后,该类型的所有对象占有的I间是一LQ不会发生变化。因此,我们可以用sizeof来计一个类型或者该cd的某个实例来得到寸信息。下面的代码是等L


int iVal;
//sizeof type
sizeof(int)
//sizeof instance
sizeof(iVal)

无论我们用iValq是intQ上面的表达式都会返回intcd的尺寸(当然如前所_iVal的尺寸和其类型尺寸永q是一L)?/p>

不熟悉sizeof的朋友往往会在处理指针时弄错概c考虑下面代码Q?/p>

int iArray[10];
int sizeofArray=sizeof(iArray);

int * p= new int[10];
int sizeofPointer = sizeof(p);

在很多h心目中,指针和数l是{h的,但是事实严格hq不如此。上面的代码׃q回不同的结果?/p>

对于iArrayQ它的类型是int[10]Q是一个数l,sizeof计算其尺寸时Q知道它包含10个元素,每个元素都时个整型,因此q回40。而对于pQ它的类型是int*Q指针的寸永远?Q因此结果就?。sizeof不会也不可能知道p实际指向10个元素的数组?/p>

出现q个问题的原因有两个Q?. sizeof是在~译时计的Q而new int[10]指向的数l是在运行时创徏的,也就是说当sizeof(p)计算Ӟpȝq不知道p会指向多个int元素Q自然也不可能知道它指向的数l占有多字节?. sizeof计算的是p自己的类型所占据的空_而不是p指向的对象所占据的空_可以_p自己占据4个字节,而p指向的空间占40字节?/p>

在这U概念下Q我们是不是可以通过sizeof(*p)来得?0呢?很不q,不行Q原因是p的类型是int*Q?p的类型是intQ因此无法得到其是一个数l的事实?/p>

实际上,q个寸信息是个q行时数据,作ؓC/C++语言而言Q是无从知道q个信息的(因ؓC/C++指针不包含这U信息)Q要得到它,唯一的办法是指望操作pȝ在运行时中提供。在VC中,我们可以通过_msize得到?/p>

2. 寚w问题

我们在访问内存时Q如果地址是按4字节寚wQ则讉K效率会高很多。这个问题的原因在于讉K内存的硬件电路。一般情况下Q地址ȝL按照寚w后的地址来访问。例如你惛_?x00000001开始的4字节内容Q系l首先需要以0x00000000?字节Q然后从中取?字节Q然后在?x00000004作ؓ开始地址Q获得下一个四字节Q在从中得到W一个字节,两次l合Z惛_到的内容。但是如果地址一开始就是对齐到0x00000000Q则pȝ只要一ơ读写即可?/p>

Z性能考虑Q编译器会对l构q行寚w处理。考虑下面的结?/p>

 

struct aStruct
{
               
char cValue;
               
int    iValue;
}
;

 

直观的讲Q这个结构的寸是sizeof(char)+sizeof(int)Q?,但是在实际编译下Q这个结构尺寸缺省是8Q因为第二个域ivalue会被寚w到第四个字节?/p>

在VC中,我们可以用pack预处理指令来止寚w调整。例?下面代码得结构尺寸更加紧凑,不会出现寚w?字节问题Q?/p>

 

#pragma pack(1)
struct aStruct{
     
char cValue;
    
int     iValue;
}
;
#pragma pack()

对于q个pack指o的含义,大家可以查询MSDN。请注意Q除非你觉得必须q样Q不要轻易做q样的调_因ؓq将降低E序性能。目前比较常见的用法是:1. q个l构需要被直接写入文g 2. q个l构需要通过|络传给其他E序?/p>

注意Q字节对齐是~译时决定的Q一旦决定不会再改变Q因此即使有寚w的因素在Q也不会出现一个结构在q行时尺寸发生变化的情况出现?/p>

isabc 2008-05-25 21:53 发表评论
]]>用rand()和srand()产生为随机数的方法ȝ[转]http://www.shnenglu.com/Lee7/archive/2008/05/22/50737.htmlisabcisabcThu, 22 May 2008 03:23:00 GMThttp://www.shnenglu.com/Lee7/archive/2008/05/22/50737.htmlhttp://www.shnenglu.com/Lee7/comments/50737.htmlhttp://www.shnenglu.com/Lee7/archive/2008/05/22/50737.html#Feedback1http://www.shnenglu.com/Lee7/comments/commentRss/50737.htmlhttp://www.shnenglu.com/Lee7/services/trackbacks/50737.htmlQ被包含?iostream>中)提供两个帮助生成伪随机数的函敎ͼ   阅读全文

isabc 2008-05-22 11:23 发表评论
]]>
TCP/IP 数据包头格式 Q{Q?/title><link>http://www.shnenglu.com/Lee7/archive/2008/05/16/50043.html</link><dc:creator>isabc</dc:creator><author>isabc</author><pubDate>Fri, 16 May 2008 06:50:00 GMT</pubDate><guid>http://www.shnenglu.com/Lee7/archive/2008/05/16/50043.html</guid><wfw:comment>http://www.shnenglu.com/Lee7/comments/50043.html</wfw:comment><comments>http://www.shnenglu.com/Lee7/archive/2008/05/16/50043.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Lee7/comments/commentRss/50043.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Lee7/services/trackbacks/50043.html</trackback:ping><description><![CDATA[最q狂补基Q猛看TCP/IP协议。不q,书上的东西太抽象了,没有什么数据实例,看了?久就忘了。于是,搬来一个snifferQ抓了数据包来看Q呵呵,l合书里面得讲解Q理解得 比较快。我来灌点基础知识。  <p>  <strong>开始吧Q先介绍IP协议。  </strong></p> <p>  IP协议QInternet ProtocolQ是|络层协议,用在因特|上QTCPQUDPQICMPQIGMP数据都是按照IP数据格式发送得。IP协议提供的是不可靠无q接得服务。IP数据包由一个头部和一个正文部分构成。正文主要是传输的数据,我们主要来理解头部数据,可以从其理解到IP协议。  </p> <p>  <strong>IP数据包头部格式(RFC791Q?/strong></p> <p align=center><img style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" src="http://industry.ccidnet.com/col/attachment/2007/2/1013357.jpg"><span id=ad_qqread_mid_big></span></p> <p>  <strong>Example Internet Datagram Header</strong> </p> <p>  上面的就是IP数据的头部格式,q里大概Cl一下。  </p> <p>  IP头部?0字节的固定长度和一个可选Q意长度部分构成,以大D늂机次序传送,从左?叟뀂  </p> <p>  <strong>TCP协议</strong>  </p> <p>  TCP协议QTRANSMISSION CONTROL PROTOCOLQ是传输层协议,为应用层提供服务Q和UDP不同的是QTCP协议提供的可靠的面向q接的服务。在RFC793中是基本的TCP描述。关于TCP协议的头部格式内容的说明Q  </p> <p>  <strong>TCP Header FORMat </strong></p> <p> </p> <p align=center><img style="BORDER-RIGHT: black 1px solid; BORDER-TOP: black 1px solid; BORDER-LEFT: black 1px solid; BORDER-BOTTOM: black 1px solid" src="http://industry.ccidnet.com/col/attachment/2007/2/1013359.jpg"></p> <p>  <strong>TCP Header FORMat  </strong></p> <p>  跟IP头部差不多,基本的长度也?0字节。TCP数据包是包含在一个IP数据报文中的。  </p> <p>  好了Q简单介l到此ؓ止。来看看我捕L例子吧。这是一ơFTP的连接,呵呵Q是cuteftp默认的cuteftp的FTP站点QIP地址是:216.3.226.21。我的IP地址假设?192.168.1.1。下面的数据是TCO/IPq接q程中的数据传输。我们可以分析TCP/IP协议数据格式以及TCP/IPq接的三ơ握手(ThreeWay-HandshakeQ情c下面的q些十六q制数据只是TCP/IP协议的数据,不是完整的网l通讯数据。  </p> <p>  W一ơ,我向FTP站点发送连接请求(我把TCP数据的可选部分去掉了Q </p> <p>  192.168.1.1->216.3.226.21  <br><br>  IP头部Q?45 00 00 30 52 52 40 00 80 06 2c 23 c0 a8 01 01 d8 03 e2 15  <br><br>  TCP头部Q?d 28 00 15 50 5f a9 06 00 00 00 00 70 02 40 00 c0 29 00 00  </p> <p>  来看看IP头部的数据是些什么。  </p> <p>  W一字节Q?#8220;45”Q其?#8220;4”是IP协议的版本(VersionQ,说明是IP4?#8220;5”是IHL位,表示IP头部的长度,是一?bit字段Q最大就?111了,gؓ12QIP头部的最大长度就?0字节。而这里ؓ“5”Q说明是20字节Q这是标准的IP头部长度Q头部报文中没有发送可选部分数据。  </p> <p>  接下来的一个字?#8220;00”是服务类型(Type of ServiceQ。这?bit字段?bit的优先权子字D(现在已经被忽略)Q? bit的TOS子字D以? bit的未用字D(现在?Q构?4 bit的TOS子字D包含:最g时、最大吞吐量、最高可靠性以及最费用构成,q四?bit位最多只能有一个ؓ1Q本例中都ؓ0Q表C是一般服务。  </p> <p>  接着的两个字?#8220;00 30”是IP数据报文总长Q包含头部以及数据,q里表示48字节。这48字节?0字节的IP头部以及28字节的TCP头构成(本来截取的TCP头应该是28字节的,其中8字节为可选部分,被我省去了)。因此目前最大的IP数据包长度是65535字节。  </p> <p>  再是两个字节的标志位QIdentificationQ:“5252”Q{换ؓ十进制就?1074。这个是让目的主机来判断新来的分D属于哪个分l。  </p> <p>  下一个字?#8220;40”Q{换ؓ二进制就?#8220;0100 0000”Q其中第一位是IP协议目前没有用上的,?。接着的是两个标志DF和MF。DF?表示不要分段QMF?表示q有q一步的分段Q本例ؓ0Q。然后的“0 0000”是分D便U(Fragment OffsetQ。  </p> <p>  “80”q个字节是TTLQTime To LiveQ了Q表CZ个IP数据的生命周期Q用Ping昄的结果,能得到TTL的|很多文章p通过TTL位来判别Lcd。因Z般主机都有默认的TTL|不同pȝ的默认g一栗比如WINDOWS?28。不q,一般Ping得到的都不是默认|q是因ؓ每次IP数据包经q一个\由器的时候TTL减一Q当减到0Ӟq个数据包就消亡了。这也时Tracert的原理。本例中?#8220;80”Q{换ؓ十进制就?28了,我用的WIN2000。  </p> <p>  l箋下来的是“06”Q这个字节表CZ输层的协议类型(ProtocolQ。在RFC790中有定义Q?表示传输层是TCP协议。  </p> <p>  “2c 23”q个16bit是头校验和(Header ChecksumQ。  </p> <p>  接下?#8220;c0 a8 01 01”Q这个就是源地址QSource AddressQ了Q也是我的IP地址?</p> <p>  转换为十q制的IP地址是Q?92.168.1.1Q同Pl箋下来?2?#8220;d8 03 e2 15”是目标地址Q?16.3.226.21  </p> <p>  好了Q真累啊Q终于看完基本的20字节的IP数据报头了。l看TCP的头部吧Q这个是作ؓIP数据包的数据部分传输的。  </p> <p>  TCP头部Q?d 28 00 15 50 5f a9 06 00 00 00 00 70 02 40 00 c0 29 00 00  </p> <p>  一来就是一个两字节D?#8220;0d 28”Q表C本地端口号Q{换ؓ十进制就?368。第二个两字节段“00 15”表示目标端口Q因为我是连接FTP站点Q所以,q个是21啦,十六q制当然是“00 15”。  </p> <p>  接下来的四个字节“50 5f a9 06”是顺序号QSequence NumberQ,写ؓSEQQSEQ=1348446470下面的四个字?#8220;00 00 00 00”是确认号QAcknowledgment NumberQ,写ؓACKNUM。  </p> <p>  l箋两个字节Q?#8220;70 02”Q{换ؓ二进制吧Q?#8220;0111 0000 0000 0010”。这两个字节,d16bitQ有好多东西呢。第一?bit“0111”Q是TCP头长Q十q制?Q表C?8个字节(刚才说了Q我省略?字节的option数据Q所以你只看见了20字节Q。接着?bit现在TCP协议没有用上Q都?。最后的6bit“00 0010”是六个重要的标志。这是两个计机数据交流的信息标志。接收和发送断Ҏq些标志来确定信息流的种cR下面是一些介l:  </p> <p>  URGQ(Urgent Pointer field significantQ紧急指针。用到的时候gؓ1Q用来处理避免TCP数据中断  </p> <p>  ACKQ(Acknowledgment fieldsignificantQ置1时表C确认号QAcknowledgmentNumberQؓ合法Qؓ0的时候表C数据段不包含确认信息,认可忽略。  </p> <p>  PSHQ(Push FunctionQ,PUSH标志的数据,|?时请求的数据D在接收方得到后可直接送到应用E序Q而不必等到缓冲区满时才传送。  </p> <p>  RSTQ(Reset the connectionQ用于复位因某种原因引v出现的错误连接,也用来拒l非法数据和h。如果接收到RST位时候,通常发生了某些错误。  </p> <p>  SYNQ(Synchronize sequence numbersQ用来徏立连接,在连接请求中QSYN=1QACK=0Q连接响应时QSYN=1QACK=1。即QSYN和ACK来区分Connection Request和Connection Accepted。  </p> <p>  FINQ(No more data from senderQ用来释放连接,表明发送方已经没有数据发送了。  </p> <p>  q?个标志位Q你们自己对号入座吧。本例中SYN=1QACK=0Q当然就是表C接请求了。我们可以注意下面两个过E的q两位的变换。  </p> <p>  后面?#8220;40 00 c0 29 00 00”不讲了,呵呵Q偷懒了。后面两ơ通讯的数据,自己分开看吧。我们看看连接的q程Q一些重要地方的变化。  </p> <p>  W二ơ,FTP站点q回一个可以连接的信号。  </p> <p>  216.3.226.21->192.168.1.1  </p> <p>  IP头部Q?45 00 00 2c c6 be 40 00 6a 06 cd ba d8 03 e2 15 c0 a8 01 01  <br><br>  TCP头部Q?0 15 0d 28 4b 4f 45 c1 50 5f a9 07 60 12 20 58 64 07 00 00  </p> <p>  W三ơ,我确认连接。TCPq接建立h。  </p> <p>  192.168.1.1->216.3.226.21  <br><br>  IP头部Q?45 00 00 28 52 53 40 00 80 06 2c 2a c0 a8 01 01 d8 03 e2 15  <br><br>  TCP头部Q?d 28 00 15 50 5f a9 07 4b 4f 45 c2 50 10 40 b0 5b 1c 00 00  </p> <p>  好,我们看看整个Threeway_handshakeq程。  <br><br>  W一步,我发接请求,TCP数据为:SEQ=50 5f a9 06QACKNUM=00 00 00 00QSYN=1QACK=0。  </p> <p>  W二步,Ҏ认可以q接QTCP数据为:SEQ=4b 4f 45 c1QACKNUM=50 5f a9 07QSYN=1QACK=1。  </p> <p>  W三步,我确认徏立连接。SEQ=50 5f a9 07Q?ACKNUM=4b 4f45c2QSYN=0QACK=1。  </p> <p>  可以看出什么变化么Q正式徏立连接了呢,q些东西是什么|  </p> <p>  我接收从216.3.226.21->192.168.1.1的下一个数据包中:  </p> <p>  SEQ=4b 4f 45 c2QACKNUM=50 5f a9 07,SYN=0,ACK=1q些都是很基的东西,对于~写snifferq样的东西是必须非常熟悉的。这里只讲解了TCP/IP协议的一点点东西Q主要是头部数据的格?/p> <img src ="http://www.shnenglu.com/Lee7/aggbug/50043.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Lee7/" target="_blank">isabc</a> 2008-05-16 14:50 <a href="http://www.shnenglu.com/Lee7/archive/2008/05/16/50043.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++中的虚函?virtual function)http://www.shnenglu.com/Lee7/archive/2008/04/27/48227.htmlisabcisabcSat, 26 Apr 2008 17:15:00 GMThttp://www.shnenglu.com/Lee7/archive/2008/04/27/48227.htmlhttp://www.shnenglu.com/Lee7/comments/48227.htmlhttp://www.shnenglu.com/Lee7/archive/2008/04/27/48227.html#Feedback0http://www.shnenglu.com/Lee7/comments/commentRss/48227.htmlhttp://www.shnenglu.com/Lee7/services/trackbacks/48227.html阅读全文

isabc 2008-04-27 01:15 发表评论
]]>
C++的static关键?/title><link>http://www.shnenglu.com/Lee7/archive/2008/04/27/48224.html</link><dc:creator>isabc</dc:creator><author>isabc</author><pubDate>Sat, 26 Apr 2008 17:00:00 GMT</pubDate><guid>http://www.shnenglu.com/Lee7/archive/2008/04/27/48224.html</guid><wfw:comment>http://www.shnenglu.com/Lee7/comments/48224.html</wfw:comment><comments>http://www.shnenglu.com/Lee7/archive/2008/04/27/48224.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Lee7/comments/commentRss/48224.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Lee7/services/trackbacks/48224.html</trackback:ping><description><![CDATA[     摘要: 作者:韩耀?  C++的static有两U用法:面向q程E序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数Q不涉及c;后者主要说明static在类中的作用?一、面向过E设计中的static 1、静态全局变量 在全局变量前,加上关键字staticQ该变量p定义成ؓ一个静态全局变量。我们先举一个静态全局变量的例子,如下Q? //Example&nb...  <a href='http://www.shnenglu.com/Lee7/archive/2008/04/27/48224.html'>阅读全文</a><img src ="http://www.shnenglu.com/Lee7/aggbug/48224.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Lee7/" target="_blank">isabc</a> 2008-04-27 01:00 <a href="http://www.shnenglu.com/Lee7/archive/2008/04/27/48224.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>vc自定义消息的发送与接收的方法实?http://www.shnenglu.com/Lee7/archive/2008/04/22/47845.htmlisabcisabcTue, 22 Apr 2008 13:17:00 GMThttp://www.shnenglu.com/Lee7/archive/2008/04/22/47845.htmlhttp://www.shnenglu.com/Lee7/comments/47845.htmlhttp://www.shnenglu.com/Lee7/archive/2008/04/22/47845.html#Feedback2http://www.shnenglu.com/Lee7/comments/commentRss/47845.htmlhttp://www.shnenglu.com/Lee7/services/trackbacks/47845.html

以下用一个自创的对话框类(MyMessageDlg)向视囄(MessageTestView)
发送自定义消息ZQ说明这两种不同Ҏ的自定义消息?/span>

消息传递的Ҏ一Q用ON_MESSAGE
使用ON_MESSAGE响应消息Q必配合定义消?define WM_MY_MESSAGE (WM_USER+100)

对于发送消息?/span>-MyMessageDlgQ?br>在其MyMessageDlg.h中,定义#define WM_MY_MESSAGE (WM_USER+100)
在其MyMessageDlg.cpp中要先添加:Qi nclude "MainFrm.h"
因ؓ使用了CMainFrame*定义对象?br>q且要有试消息的函敎ͼ
void MyMessageDlg::OnButtonMsg()
{
    // TODO: Add your control notification handler code here
    CMainFrame* pMF=(CMainFrame*)AfxGetApp()->m_pMainWnd;  //先通过获取当前框架指针
    CView * active = pMF->GetActiveView();//才能获取当前视类指针
    if(active != NULL)  //获取了当前视cL针才能发送消?br>    active->PostMessage(WM_MY_MESSAGE,0,0);   //使用PostMessage发送消?br>}

对于消息的接受?/span>-MessageTestViewQ?br>在其MessageTestView.h中,也要定义#define WM_MY_MESSAGE (WM_USER+100)
q定义消息映函?OnMyMessage()
protected:
 //{{AFX_MSG(CMessageTestView)
 afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
在其MessageTestView.cpp中,
先要声明响应消息Q?br>BEGIN_MESSAGE_MAP(CMessageTestView, CEditView)
 //{{AFX_MSG_MAP(CMessageTestView)
 ON_MESSAGE(WM_MY_MESSAGE, OnMyMessage)
 //}}AFX_MSG_MAP
再添加消息响应的函数实现Q?br>LRESULT CMessageTestView::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
 MessageBox("OnMyMessage!");
 return 0;
}


消息传递的Ҏ二:使用ON_REGISTERED_MESSAGE
使用ON_REGISTERED_MESSAGE注册消息Q必配?br>static UINT WM_MY_MESSAGE=RegisterWindowMessage("Message");

对于消息的发送?/span>-MyMessageDlgQ?br>在其MyMessageDlg.h中,只要
定义static UINT WM_MY_MESSAGE=RegisterWindowMessage("Message");
可以了?br>在其MyMessageDlg.cpp中要先添加:Qi nclude "MainFrm.h"
因ؓ使用了CMainFrame*定义对象?br>q且要有试消息的函敎ͼ
void MyMessageDlg::OnButtonMsg()
{
    // TODO: Add your control notification handler code here
    CMainFrame* pMF=(CMainFrame*)AfxGetApp()->m_pMainWnd;  //先通过获取当前框架指针
    CView * active = pMF->GetActiveView();//才能获取当前视类指针
    if(active != NULL)  //获取了当前视cL针才能发送消?br>    active->PostMessage(WM_MY_MESSAGE,0,0);   //使用PostMessage发送消?br>}

对于消息的接收?/span>-MessageTestViewQ?br>在其MessageTestView.h中不要定?br>static UINT WM_MY_MESSAGE=RegisterWindowMessage("Message");
应该把这个定义放到MessageTestView.cpp中,要不会出? redefinition
在其MessageTestView.h中只要定义消息映函?br>protected:
 //{{AFX_MSG(CMessageTestView)
 afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
在其MessageTestView.cpp?先定?br>static UINT WM_MY_MESSAGE=RegisterWindowMessage("Message");
接着注册消息Q?br>BEGIN_MESSAGE_MAP(CMessageTestView, CEditView)
 //{{AFX_MSG_MAP(CMessageTestView)
        ON_REGISTERED_MESSAGE(WM_MY_MESSAGE,OnMyMessage)
 //}}AFX_MSG_MAP
最后添加消息响应的函数实现Q?br>LRESULT CMessageTestView::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
 MessageBox("OnMyMessage!");
 return 0;
}
----------------------------------------------------------------
比较两种ҎQ只是略有不同。但也要心谨慎Q以免出现接收不到消息的情况?/p>

-------------------------------------------------------------------

其他注意事项Q?/p>

发送消息的-MyMessageDlg.cpp前也要定?br>static UINT WM_MY_MESSAGE=RegisterWindowMessage("Message");

接受消息?MessageTestView.cpp前也要定?br>static UINT WM_MY_MESSAGE=RegisterWindowMessage("Message");

RegisterWindowMessage("Message")?"的内Ҏ什么不重要Q写什么都可以Q但?br>发送者与接受者必L一L内容Q例如:"Message"



isabc 2008-04-22 21:17 发表评论
]]>
文档工程中类之间怺指针的获?/title><link>http://www.shnenglu.com/Lee7/archive/2008/04/15/47162.html</link><dc:creator>isabc</dc:creator><author>isabc</author><pubDate>Tue, 15 Apr 2008 14:41:00 GMT</pubDate><guid>http://www.shnenglu.com/Lee7/archive/2008/04/15/47162.html</guid><wfw:comment>http://www.shnenglu.com/Lee7/comments/47162.html</wfw:comment><comments>http://www.shnenglu.com/Lee7/archive/2008/04/15/47162.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Lee7/comments/commentRss/47162.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Lee7/services/trackbacks/47162.html</trackback:ping><description><![CDATA[     摘要: 1) 在View中获得Doc指针2) 在App中获得MainFrame指针3) 在View中获得MainFrame指针4) 获得ViewQ已建立Q指?) 获得当前文指针6) 获得状态栏与工h指针7) 获得状态栏与工h变量8) 在Mainframe获得菜单指针9) 在Q何类中获得应用程序类10) 从文类取得视图cȝ指针(1)11) 在App中获得文档模板指?2) 从文档模板获得文类指针13) 在文档类中获得文模板指?4) 从文类取得视图cȝ指针(2)15) 从一个视囄取得另一视图cȝ指针  <a href='http://www.shnenglu.com/Lee7/archive/2008/04/15/47162.html'>阅读全文</a><img src ="http://www.shnenglu.com/Lee7/aggbug/47162.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Lee7/" target="_blank">isabc</a> 2008-04-15 22:41 <a href="http://www.shnenglu.com/Lee7/archive/2008/04/15/47162.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>c++中的list用法http://www.shnenglu.com/Lee7/archive/2008/04/14/47036.htmlisabcisabcMon, 14 Apr 2008 05:48:00 GMThttp://www.shnenglu.com/Lee7/archive/2008/04/14/47036.htmlhttp://www.shnenglu.com/Lee7/comments/47036.htmlhttp://www.shnenglu.com/Lee7/archive/2008/04/14/47036.html#Feedback1http://www.shnenglu.com/Lee7/comments/commentRss/47036.htmlhttp://www.shnenglu.com/Lee7/services/trackbacks/47036.html 

#include <iostream> 
#include 
<list> 
#include 
<numeric> 
#include 
<algorithm> 

using namespace std; 

//创徏一个list容器的实例LISTINT 
typedef list<int> LISTINT; 

//创徏一个list容器的实例LISTCHAR 
typedef list<int> LISTCHAR; 

void main(void

    
//-------------------------- 
    
//用list容器处理整型数据 
    
//-------------------------- 
    
//用LISTINT创徏一个名为listOne的list对象 
    LISTINT listOne; 
    
//声明iP代器 
    LISTINT::iterator i; 
    
    
//从前面向listOne容器中添加数?nbsp;
    listOne.push_front (2); 
    listOne.push_front (
1); 
    
    
//从后面向listOne容器中添加数?nbsp;
    listOne.push_back (3); 
    listOne.push_back (
4); 
    
    
//从前向后昄listOne中的数据 
    cout<<"listOne.begin()--- listOne.end():"<<endl; 
    
for (i = listOne.begin(); i != listOne.end(); ++i) 
        cout 
<< *<< " "
    cout 
<< endl; 
    
    
//从后向后昄listOne中的数据 
    LISTINT::reverse_iterator ir; 
    cout
<<"listOne.rbegin()---listOne.rend():"<<endl; 
    
for (ir =listOne.rbegin(); ir!=listOne.rend();ir++
        cout 
<< *ir << " "
    }
 
    cout 
<< endl; 
    
    
//使用STL的accumulate(累加)法 
    int result = accumulate(listOne.begin(), listOne.end(),0); 
    cout
<<"Sum="<<result<<endl; 
    cout
<<"------------------"<<endl; 
    
    
//-------------------------- 
    
//用list容器处理字符型数?nbsp;
    
//-------------------------- 
    
    
//用LISTCHAR创徏一个名为listOne的list对象 
    LISTCHAR listTwo; 
    
//声明iP代器 
    LISTCHAR::iterator j; 
    
    
//从前面向listTwo容器中添加数?nbsp;
    listTwo.push_front ('A'); 
    listTwo.push_front (
'B'); 
    
    
//从后面向listTwo容器中添加数?nbsp;
    listTwo.push_back ('x'); 
    listTwo.push_back (
'y'); 
    
    
//从前向后昄listTwo中的数据 
    cout<<"listTwo.begin()---listTwo.end():"<<endl; 
    
for (j = listTwo.begin(); j != listTwo.end(); ++j) 
        cout 
<< char(*j) << " "
    cout 
<< endl; 
    
    
//使用STL的max_element法求listTwo中的最大元素ƈ昄 
    j=max_element(listTwo.begin(),listTwo.end()); 
    cout 
<< "The maximum element in listTwo is: "<<char(*j)<<endl; 
}
 

#include 
<iostream> 
#include 
<list> 

using namespace std; 
typedef list
<int> INTLIST; 

//从前向后昄list队列的全部元?nbsp;
void put_list(INTLIST list, char *name) 

    INTLIST::iterator plist; 
    
    cout 
<< "The contents of " << name << " : "
    
for(plist = list.begin(); plist != list.end(); plist++
        cout 
<< *plist << " "
    cout
<<endl; 
}
 

//试list容器的功?nbsp;
void main(void

    
//list1对象初始为空 
    INTLIST list1; 
    
//list2对象最初有10个gؓ6的元?nbsp;
    INTLIST list2(10,6); 
    
//list3对象最初有3个gؓ6的元?nbsp;
    INTLIST list3(list2.begin(),--list2.end()); 
    
    
//声明一个名为i的双向P代器 
    INTLIST::iterator i; 
    
    
//从前向后昄各list对象的元?nbsp;
    put_list(list1,"list1"); 
    put_list(list2,
"list2"); 
    put_list(list3,
"list3"); 
    
    
//从list1序列后面d两个元素 
    list1.push_back(2); 
    list1.push_back(
4); 
    cout
<<"list1.push_back(2) and list1.push_back(4):"<<endl; 
    put_list(list1,
"list1"); 
    
    
//从list1序列前面d两个元素 
    list1.push_front(5); 
    list1.push_front(
7); 
    cout
<<"list1.push_front(5) and list1.push_front(7):"<<endl; 
    put_list(list1,
"list1"); 
    
    
//在list1序列中间插入数据 
    list1.insert(++list1.begin(),3,9); 
    cout
<<"list1.insert(list1.begin()+1,3,9):"<<endl; 
    put_list(list1,
"list1"); 
    
    
//试引用cd?nbsp;
    cout<<"list1.front()="<<list1.front()<<endl; 
    cout
<<"list1.back()="<<list1.back()<<endl; 
    
    
//从list1序列的前后各Ud一个元?nbsp;
    list1.pop_front(); 
    list1.pop_back(); 
    cout
<<"list1.pop_front() and list1.pop_back():"<<endl; 
    put_list(list1,
"list1"); 
    
    
//清除list1中的W?个元?nbsp;
    list1.erase(++list1.begin()); 
    cout
<<"list1.erase(++list1.begin()):"<<endl; 
    put_list(list1,
"list1"); 
    
    
//对list2赋值ƈ昄 
    list2.assign(8,1); 
    cout
<<"list2.assign(8,1):"<<endl; 
    put_list(list2,
"list2"); 
    
    
//昄序列的状态信?nbsp;
    cout<<"list1.max_size(): "<<list1.max_size()<<endl; 
    cout
<<"list1.size(): "<<list1.size()<<endl; 
    cout
<<"list1.empty(): "<<list1.empty()<<endl; 
    
    
//list序列容器的运?nbsp;
    put_list(list1,"list1"); 
    put_list(list3,
"list3"); 
    cout
<<"list1>list3: "<<(list1>list3)<<endl; 
    cout
<<"list1<list3: "<<(list1<list3)<<endl; 
    
    
//对list1容器排序 
    list1.sort(); 
    put_list(list1,
"list1"); 
    
    
//l合处理 
    list1.splice(++list1.begin(), list3); 
    put_list(list1,
"list1"); 
    put_list(list3,
"list3"); 
}
 



isabc 2008-04-14 13:48 发表评论
]]>
List,set,Map 的用法和区别{?[转]http://www.shnenglu.com/Lee7/archive/2008/04/14/47037.htmlisabcisabcMon, 14 Apr 2008 05:48:00 GMThttp://www.shnenglu.com/Lee7/archive/2008/04/14/47037.htmlhttp://www.shnenglu.com/Lee7/comments/47037.htmlhttp://www.shnenglu.com/Lee7/archive/2008/04/14/47037.html#Feedback0http://www.shnenglu.com/Lee7/comments/commentRss/47037.htmlhttp://www.shnenglu.com/Lee7/services/trackbacks/47037.htmlCollection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap

Collection接口
  Collection是最基本的集合接口,一个Collection代表一lObjectQ即Collection的元素(ElementsQ。一?Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接承自Collection的类QJava SDK提供的类都是l承自Collection?#8220;子接?#8221;如List和Set?br>  所有实现Collection接口的类都必L供两个标准的构造函敎ͼ无参数的构造函数用于创Z个空的CollectionQ有一?Collection参数的构造函数用于创Z个新的CollectionQ这个新的Collection与传入的Collection有相同的元素。后一个构造函数允许用户复制一个Collection?br>  如何遍历Collection中的每一个元素?不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个P代子Q用该q代子即可逐一讉KCollection中每一个元素。典型的用法如下Q?br>    Iterator it = collection.iterator(); // 获得一个P代子
    while(it.hasNext()) {
      Object obj = it.next(); // 得到下一个元?br>    }
  由Collection接口z的两个接口是List和Set?br>
List接口
  List是有序的CollectionQ用此接口能够_的控制每个元素插入的位置。用戯够用烦引(元素在List中的位置Q类g数组下标Q来讉KList中的元素Q这cM于Java的数l?br>和下面要提到的Set不同QList允许有相同的元素?br>  除了hCollection接口必备的iterator()Ҏ外,Listq提供一个listIterator()ҎQ返回一?ListIterator接口Q和标准的Iterator接口相比QListIterator多了一些add()之类的方法,允许dQ删除,讑֮元素Q还能向前或向后遍历?br>  实现List接口的常用类有LinkedListQArrayListQVector和Stack?br>
LinkedListc?br>  LinkedList实现了List接口Q允许null元素。此外LinkedList提供额外的getQremoveQinsertҎ?LinkedList的首部或N。这些操作LinkedList可被用作堆栈QstackQ,队列QqueueQ或双向队列QdequeQ?br>  注意LinkedList没有同步Ҏ。如果多个线E同时访问一个ListQ则必须自己实现讉K同步。一U解x法是在创建List时构造一个同步的ListQ?br>    List list = Collections.synchronizedList(new LinkedList(...));

ArrayListc?br>  ArrayList实现了可变大的数组。它允许所有元素,包括null。ArrayList没有同步?br>sizeQisEmptyQgetQsetҎq行旉为常数。但是addҎ开销为分摊的常数Q添加n个元素需要O(n)的时间。其他的Ҏq行旉为线性?br>  每个ArrayList实例都有一个容量(CapacityQ,即用于存储元素的数组的大。这个容量可随着不断d新元素而自动增加,但是增长法q没有定义。当需要插入大量元素时Q在插入前可以调用ensureCapacityҎ来增加ArrayList的容量以提高插入效率?br>  和LinkedList一PArrayList也是非同步的QunsynchronizedQ?br>
Vectorc?br>  Vector非常cMArrayListQ但是Vector是同步的。由Vector创徏的IteratorQ虽然和ArrayList创徏?Iterator是同一接口Q但是,因ؓVector是同步的Q当一个Iterator被创且正在被用,另一个线E改变了Vector的状态(例如Q添加或删除了一些元素)Q这时调用Iterator的方法时抛出ConcurrentModificationExceptionQ因此必L莯异常?br>
Stack c?br>  Stackl承自VectorQ实C个后q先出的堆栈。Stack提供5个额外的Ҏ使得Vector得以被当作堆栈用。基本的push和pop ҎQ还有peekҎ得到栈顶的元素,emptyҎ试堆栈是否为空QsearchҎ一个元素在堆栈中的位置。Stack刚创建后是空栈?br>
Set接口
  Set是一U不包含重复的元素的CollectionQ即L的两个元素e1和e2都有e1.equals(e2)=falseQSet最多有一个null元素?br>  很明显,Set的构造函数有一个约束条Ӟ传入的Collection参数不能包含重复的元素?br>  h意:必须心操作可变对象QMutable ObjectQ。如果一个Set中的可变元素改变了自w状态导致Object.equals(Object)=true导致一些问题?br>
Map接口
  h意,Map没有l承Collection接口QMap提供key到value的映。一个Map中不能包含相同的keyQ每个key只能映射一?value。Map接口提供3U集合的视图QMap的内容可以被当作一lkey集合Q一lvalue集合Q或者一lkey-value映射?br>
Hashtablec?br>  Hashtablel承Map接口Q实C个key-value映射的哈希表。Q何非I(non-nullQ的对象都可作ؓkey或者value?br>  d数据使用put(key, value)Q取出数据用get(key)Q这两个基本操作的时间开销为常数?br>Hashtable通过initial capacity和load factor两个参数调整性能。通常~省的load factor 0.75较好地实C旉和空间的均衡。增大load factor可以节省I间但相应的查找旉增大,q会影响像get和putq样的操作?br>使用Hashtable的简单示例如下,?Q?Q?攑ֈHashtable中,他们的key分别?#8221;one”Q?#8221;two”Q?#8221;three”Q?br>    Hashtable numbers = new Hashtable();
    numbers.put(“one”, new Integer(1));
    numbers.put(“two”, new Integer(2));
    numbers.put(“three”, new Integer(3));
  要取Z个数Q比?Q用相应的keyQ?br>    Integer n = (Integer)numbers.get(“two”);
    System.out.println(“two = ” + n);
  ׃作ؓkey的对象将通过计算其散列函数来定与之对应的value的位|,因此M作ؓkey的对象都必须实现hashCode和equalsҎ。hashCode和equalsҎl承自根cObjectQ如果你用自定义的类当作key的话Q要相当心Q按照散列函数的定义Q如果两个对象相同,即obj1.equals(obj2)=trueQ则它们的hashCode必须相同Q但如果两个对象不同Q则它们的hashCode不一定不同,如果两个不同对象的hashCode相同Q这U现象称为冲H,冲突会导致操作哈希表的时间开销增大Q所以尽量定义好的hashCode()ҎQ能加快哈希表的操作?br>  如果相同的对象有不同的hashCodeQ对哈希表的操作会出现意想不到的l果Q期待的getҎq回nullQ,要避免这U问题,只需要牢C条:要同时复写equalsҎ和hashCodeҎQ而不要只写其中一个?br>  Hashtable是同步的?br>
HashMapc?br>  HashMap和HashtablecMQ不同之处在于HashMap是非同步的,q且允许nullQ即null value和null key。,但是HashMap视ؓCollectionӞvalues()Ҏ可返回CollectionQ,其P代子操作旉开销和HashMap 的容量成比例。因此,如果q代操作的性能相当重要的话Q不要将HashMap的初始化定w讑־q高Q或者load factorq低?br>
WeakHashMapc?br>  WeakHashMap是一U改q的HashMapQ它对key实行“弱引?#8221;Q如果一个key不再被外部所引用Q那么该key可以被GC回收?br>
ȝ
  如果涉及到堆栈,队列{操作,应该考虑用ListQ对于需要快速插入,删除元素Q应该用LinkedListQ如果需要快速随问元素,应该使用ArrayList?br>  如果E序在单U程环境中,或者访问仅仅在一个线E中q行Q考虑非同步的c,其效率较高,如果多个U程可能同时操作一个类Q应该用同步的cR?br>  要特别注意对哈希表的操作Q作为key的对象要正确复写equals和hashCodeҎ?br>  量q回接口而非实际的类型,如返回List而非ArrayListQ这样如果以后需要将ArrayList换成LinkedListӞ客户端代码不用改变。这是针对抽象~程?nbsp;


isabc 2008-04-14 13:48 发表评论
]]>
MFC中自׃用自定义消息http://www.shnenglu.com/Lee7/archive/2008/03/31/45826.htmlisabcisabcMon, 31 Mar 2008 09:10:00 GMThttp://www.shnenglu.com/Lee7/archive/2008/03/31/45826.htmlhttp://www.shnenglu.com/Lee7/comments/45826.htmlhttp://www.shnenglu.com/Lee7/archive/2008/03/31/45826.html#Feedback0http://www.shnenglu.com/Lee7/comments/commentRss/45826.htmlhttp://www.shnenglu.com/Lee7/services/trackbacks/45826.html
  W一?定义消息?br>
  推荐用户自定义消息至是WM_USER+100Q因为很多新控g也要使用WM_USER消息?br>
#define WM_MY_MESSAGE (WM_USER+100)

  W二?实现消息处理函数。该函数使用WPRAM和LPARAM参数q返回LPESULT?

LPESULT CMainFrame::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
// TODO: 处理用户自定义消?
...
return 0;
}

  W三?在类头文件的AFX_MSG块中说明消息处理函数:

class CMainFrame:public CMDIFrameWnd
{
...
// 一般消息映函?
protected:
// {{AFX_MSG(CMainFrame)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnTimer(UINT nIDEvent);
afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
}

  W四?在用L的消息块中,使用ON_MESSAGE宏指令将消息映射到消息处理函C?

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_WM_TIMER()
ON_MESSAGE(WM_MY_MESSAGE, OnMyMessage)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
  如果用户需要一个定义整个系l唯一的消?可以调用SDK函数RegisterWindowMessage定义消息:

static UINT WM_MY_MESSAGE=RegisterWindowMessage("User");

  q用ON_REGISTERED_MESSAGE宏指令取代ON_MESSAGE宏指?其余步骤同上?br>
  当需要用自定义消息?可以在相应类中的函数中调用函数PostMessage或SendMessage发送消息PoseMessage(WM_MY_MESSAGE,O,O); 如果向其他进E发送消息可通过如下Ҏ发送消?

DWORD result;
SendMessageTimeout(wnd->m_hWnd, // 目标H口
WM_MY_MESSAGE, // 消息
0, // WPARAM
0, // LPARAM
SMTO_ABORTIFHUNG |
SMTO_NORMAL,
TIMEOUT_INTERVAL,
&result);

  以避免其它进E如果被d而造成pȝȝ状态?br>
  可是如果需要向其它c?如主框架、子H口、视cR对话框、状态条、工h或其他控件等)发送消息时,上述Ҏ昑־无能为力Q而在~程q程中往往需要获取其它类中的某个识别信号,MFC框架l我们造成了种U限?但是可以通过获取某个cȝ指针而向q个cd送消息,而自定义消息的各U动作则在这个类中定义,q样可以自p在的向其它类发送消息了?br>
  下面丄例子叙述了向视类和框架类发送消息的ҎQ?br>
  在主框架cM向视cd送消息:

  视类中定义消息:

ON_REGISTERED_MESSAGE(WM_MY_MESSAGE,OnMyMessage) //定义消息映射
视类定义消息处理函数Q?br>
// 消息处理函数
LRESULT CMessageView::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
// TODO: 处理用户自定义消?
...
return 0;
}

//发送消息的试函数
void CMainFrame::OnTest()
{
CView * active = GetActiveView();//获取当前视类指针
if(active != NULL)
active->PostMessage(WM_MY_MESSAGE,0,0);
}

  在其它类中向视类发送消息:

//发送消息的试函数
void CMainFrame::OnTest()
{
CMDIFrameWnd *pFrame;
CMDIChildWnd *pChild;
CView *pView;
//获取ȝ口指?br>pFrame =(CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;
// 获取子窗口指?br>pChild = (CMDIChildWnd *) pFrame->GetActiveFrame();
//获取视类指针
pView = pChild->GetActiveView();
if(pView != NULL)
pView->PostMessage(WM_MY_MESSAGE,0,0);//发送消?br>}

  其余步骤同上?br>  在视cM向主框架发送消?

  首先在主框架中定义相关的消息,Ҏ同上,然后在发送消息的函数中添加代码如?br>
//发送消息的试函数
void CMessageView::OnTest()
{
CFrameWnd * active = GetActiveFrame();//获取当前ȝ口框架指?br>if(active != this)
active->PostMessage(WM_MY_MESSAGE,0,0);
return 0;
}

  在其它类中向不同的类发送消息可依次ҎcLQ这h们的E序可以的不受限制向其它类和进E发送消息,而避免了U种意想不到的风险?br>
  下面一个例子程序ؓ多文档程序里在一对话框中向视cd送消?详述了发送自定义消息的具体过E?br>  实现步骤Q?/font>

  W一步:在VC++中新建工EMessageQ所有ClassWizard步骤选项均ؓ~省,完成?br>
  W二步:在主菜单中添加测试菜单ؓ调出对话框,在框架类中徏立相应函数OnTest()

  W三步:在资源中建立对话框,通过ClassWizardd新类TestDialog,d试按钮,

  在对话框cM建立相应函数OnDialogTest()

//通过对话框按钮发送消息的函数
void TestDialog::OnDialogTest()
{
CMDIFrameWnd *pFrame;
CMDIChildWnd *pChild;
CView *pView;
//获取ȝ口指?br>pFrame =(CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;
// 获取子窗口指?br>pChild = (CMDIChildWnd *) pFrame->GetActiveFrame();
//获取视类指针
pView = pChild->GetActiveView();
if(active != NULL)
active->PostMessage(WM_MY_MESSAGE,0,0);//发送消?br>}

  在Message.h头文件中d如下语句Q?br>
static UINT WM_MY_MESSAGE=RegisterWindowMessage("Message");

  W四?在视cMd自定义消?

  在头文gMessageView.h中添加消息映?br>
protected:
//{{AFX_MSG(CMessageView)
//}}AFX_MSG
afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam); //此行为添加代?br>DECLARE_MESSAGE_MAP()
在视cL件MessageView.cpp中的消息映射中添加自定义消息映射
BEGIN_MESSAGE_MAP(CMessageView, CView)
//{{AFX_MSG_MAP(CMessageView)
//}}AFX_MSG_MAP
// Standard printing commands
ON_REGISTERED_MESSAGE(WM_MY_MESSAGE,OnMyMessage) //此行d代码定义唯一消息
END_MESSAGE_MAP()

  d相应?消息处理函数

LRESULT CMessageView::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
CRect rect;
GetClientRect(&rect);
InvalidateRect(&rect);
test=!test;
return 0;
}

  在MessageView.h中添加布变?public:BOOL test;

  在视cL造函C初始?test变量:test=FALSE;

  修改CMessageView::OnDraw()函数

void CMessageView::OnDraw(CDC* pDC)
{
CMessageDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// 以下E序昄消息响应效果
if(test)
pDC->TextOut(0,0,"消息响应!");
}

  W五步:昄试对话?br>
  在MainFramecM包含对话框头文gQ?br>
#include "TestDialog.h";
OnTest()函数中添加代?br>void CMainFrame::OnTest()
{
TestDialog dialog;
dialog.DoModal();
}

  q行E序,在测试菜单打开对话?点击试按钮卛_看到l果?br>


isabc 2008-03-31 17:10 发表评论
]]>
谈C中的malloc和freehttp://www.shnenglu.com/Lee7/archive/2008/03/22/45133.htmlisabcisabcSat, 22 Mar 2008 13:49:00 GMThttp://www.shnenglu.com/Lee7/archive/2008/03/22/45133.htmlhttp://www.shnenglu.com/Lee7/comments/45133.htmlhttp://www.shnenglu.com/Lee7/archive/2008/03/22/45133.html#Feedback0http://www.shnenglu.com/Lee7/comments/commentRss/45133.htmlhttp://www.shnenglu.com/Lee7/services/trackbacks/45133.html写下q篇文章作ؓ一个对知识的ȝ。这文章之所以命名中有个“谈”的字|也就是这个意思了Q希望对大家有一点帮助!

     如果不扯得太q的话(比如说操作系l中虚拟内存和物理内存如何运做如何管理之cȝ知识{)Q我感觉q篇文章应该是比较全面地谈了一下malloc()和free().q篇文章由浅入深Q不见得有多深)分三个部分介l主要内宏V?/p>

废话了那么多Q下面立刻进入主?===============》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》?/p>


一、malloc()和free()的基本概念以及基本用法:

1、函数原型及说明Q?/p>

void *malloc(long NumBytes)Q该函数分配了NumBytes个字节,q返回了指向q块内存的指针。如果分配失败,则返回一个空指针QNULLQ?/p>

关于分配p|的原因,应该有多U,比如说空间不_是一U?/p>

void free(void *FirstByte)Q?该函数是之前用malloc分配的空间还l程序或者是操作pȝQ也是释放了这块内存,让它重新得到自由?/p>

2、函数的用法Q?/p>

     其实q两个函数用h倒不是很难,也就是malloc()之后觉得用够了就甩了它把它给free()了,举个单例子:

E序代码Q?/font>
        // Code...
        char *Ptr = NULL;
        Ptr = (char *)malloc(100 * sizeof(char));
        if (NULL == Ptr)
    {
        exit (1);
    }
        gets(Ptr);

        // code...
        free(Ptr);
        Ptr = NULL;
        // code...

    是q样Q当Ӟ具体情况要具体分析以及具体解冟뀂比如说Q你定义了一个指针,在一个函数里甌了一块内存然后通过函数q回传递给q个指针Q那么也讔R放这块内存这工作就应该留给其他函数了?/p>

3、关于函C用需要注意的一些地方:

A、申请了内存I间后,必须查是否分配成功?/p>

B、当不需要再使用甌的内存时Q记得释放;释放后应该把指向q块内存的指针指向NULLQ防止程序后面不心使用了它?/p>

C、这两个函数应该是配寏V如果申请后不释攑ְ是内存泄Ԍ如果无故释放那就是什么也没有做。释攑֏能一ơ,如果释放两次及两ơ以上会

出现错误Q释攄指针例外Q释攄指针其实也等于啥也没做,所以释攄指针释放多少ơ都没有问题Q?/p>

D、虽然malloc()函数的类型是(void *),Mcd的指针都可以转换?void *),但是最好还是在前面q行强制cd转换Q因样可以躲q一

些编译器的检查?/p>

好了Q最基础的东西大概这么说Q现在进入第二部分:


二、malloc()到底从哪里得来了内存I间Q?/p>

1、malloc()到底从哪里得C内存I间Q答案是从堆里面获得I间。也是说函数返回的指针是指向堆里面的一块内存。操作系l中有一个记录空 闲内存地址的链表。当操作pȝ收到E序的申hQ就会遍历该链表Q然后就LW一个空间大于所甌I间的堆l点Q然后就该l点从空闲结炚w表中删除Qƈ 该l点的空间分配给E序。就是这P

   说到q里Q不得不另外插入一个小话题Q相信大家也知道是什么话题了。什么是堆?说到堆,又忍不住说到了栈Q什么是栈?下面另外开个小部分专门而又单地说一下这个题外话Q?/p>

2、什么是堆:堆是大家共有的空_分全局堆和局部堆。全局堆就是所有没有分配的I间Q局部堆是用户分配的空间。堆在操作系l对q程 初始化的时候分配,q行q程中也可以向系l要额外的堆Q但是记得用完了要还l操作系l,要不然就是内存泄漏?/p>

   什么是栈:栈是U程独有的,保存其运行状态和局部自动变量的。栈在线E开始的时候初始化Q每个线E的栈互相独立。每个函数都有自q栈,栈被用来在函C 间传递参数。操作系l在切换U程的时候会自动的切换栈Q就是切换SS/ESP寄存器。栈I间不需要在高语言里面昑ּ的分配和释放?

   以上的概忉|q是标准的描qͼ不过有个别语句被我删除,不知道因栯变得不标准了^_^.

   通过上面Ҏ늚描述Q可以知道:

   栈是q译器自动分配释放Q存攑և数的参数倹{局部变量的值等。操作方式类g数据l构中的栈?/p>

   堆一般由E序员分配释放,若不释放Q程序结束时可能由OS回收。注意这里说是可能,q一定。所以我惛_一ơ,记得要释放!

注意它与数据l构中的堆是两回事,分配方式倒是cM于链表?br>所以,举个例子Q如果你在函C面定义了一个指针变量,然后在这个函数里甌了一块内存让指针指向它。实际上Q这个指针的地址是在栈上Q但是它所指向的内容却是在堆上面的Q这一点要注意Q所以,再想惻I在一个函数里甌了空间后Q比如说下面q个函数Q?
E序代码Q?/font>
   // code...
       void Function(void)
       {
        char *p = (char *)malloc(100 * sizeof(char));
    }


  
   p个例子,千万不要认ؓ函数q回Q函数所在的栈被销毁指针也跟着销毁,甌的内存也׃栯着销毁了Q这l对是错误的Q因为申L内存在堆上,而函数所在的栈被销毁跟堆完全没有啥关系。所以,q是那句话:记得释放Q?/p>

3、free()到底释放了什?/p>

   q个问题比较单,其实我是惛_W二大部分的题目相呼应而已Q哈哈!free()释放的是指针指向的内存!注意Q释攄是内存,不是指针Q这炚w帔R帔R 要!指针是一个变量,只有E序l束时才被销毁。释放了内存I间后,原来指向q块I间的指针还是存在!只不q现在指针指向的内容的垃圾,是未定义的,所以说 是垃圾。因此,前面我已l说q了Q释攑ֆ存后把指针指向NULLQ防止指针在后面不小心又被解引用了。非帔R要啊q一点!

   好了Q这?#8220;题外?#8221;l于说完了。就q么单说一ơ,知道个大概就可以了!下面p入第三个部分Q?/p>

三、malloc()以及free()的机Ӟ

   q个部分我今天才有了新的认识Q而且是{折性的认识Q所以,q部分可能会有更多一些认识上的错误!不对的地方请大家帮忙指出Q?/p>

   事实上,仔细看一下free()的函数原型,也许也会发现g很神奇,free()函数非常单,只有一个参敎ͼ只要把指向申L间的指针传?/p>

lfree()中的参数可以完成释攑ַ作!q里要追t到malloc()的申请问题了。申L时候实际上占用的内存要比申L大。因出的I间是用来记录对q块内存的管理信息。先看一下在《UNIX环境高~程》中W七章的一D话Q?/p>

   大多数实现所分配的存储空间比所要求的要E大一些,额外的空间用来记录管理信息——分配块的长度,指向下一个分配块的指针等{。这意味着如果写过一个已 分配区的Q则会改写后一块的理信息。这U类型的错误是灾难性的Q但是因U错误不会很快就暴露出来Q所以也很隑֏现。将指向分配块的指针向后U? 动也可能会改写本块的理信息?/p>

   以上q段话已l给了我们一些信息了。malloc()甌的空间实际我觉得是分了两个不同性质的空间。一个就是用来记录管理信息的I间Q另外一个就是可用空间了。而用来记录管理信息的实际上是一个结构体。在C语言中,用结构体来记录同一个对象的不同信息?/p>

天经C的事Q下面看看这个结构体的原型:

E序代码Q?/font>
   struct mem_control_block {
    int is_available;    //q是一个标讎ͼ
    int size;            //q是实际I间的大?
    };


  
   对于size,q个是实际空间大。这里其实我有个疑问Qis_available是否是一个标讎ͼ因ؓ我看了free()的源代码之后对这个变量感觉有点纳P源代码在下面分析Q。这里还请大家指出!

   所以,free()是Ҏq个l构体的信息来释放malloc()甌的空_而结构体的两个成员的大小我想应该是操作系l的事了。但是这里有一个问 题,malloc()甌I间后返回一个指针应该是指向W二U空_也就是可用空_不然Q如果指向管理信息空间的话,写入的内容和l构体的cd有可能不 一_或者会把管理信息屏蔽掉Q那没法释攑ֆ存空间了Q所以会发生错误Q(感觉自己q里说的是废话)

   好了Q下面看看free()的源代码Q我自己分析了一下,觉得比vmalloc()的源代码倒是Ҏ单很多。只是有个疑问,下面指出Q?/p>

E序代码Q?/font>
   // code...
   
       void free(void *ptr) 
    {
            struct mem_control_block *free;
            free = ptr - sizeof(struct mem_control_block);
            free->is_available = 1;
            return;
    }

   看一下函数第二句Q这句非帔R要和关键。其实这句就是把指向可用I间的指针倒回去,让它指向理信息的那块空_因ؓq里是在g减去了一个结构体的大 !后面那一句free->is_available = 1;我有点纳P我的x是:q里is_available应该只是一个标记而已Q因Zq个变量的名UC来看Qis_available 译q来是“是可以用”。不要说我土Q我觉得变量名字可以反映一个变量的作用Q特别是严}的代码。这是源代码Q所以我觉得l对是严谨的Q!q个变量的? ?Q表明是可以用的I间Q只是这里我想了惻I如果把它改ؓ0或者是其他g知道会发生什么事Q!但是有一Ҏ可以肯定Q就是释攄对不会那么顺利进行! 因ؓq是一个标讎ͼ

   当然Q这里可能还是有Z有疑问,Z么这样就可以释放呢?Q我刚才也有q个疑问。后来我惛_Q释放是操作pȝ的事Q那么就free()q个源代码来看, 什么也没有释放Q对吧?但是它确实是定了管理信息的那块内存的内宏V所以,free()只是记录了一些信息,然后告诉操作pȝ那块内存可以去释放,具体 怎么告诉操作pȝ的我不清楚,但我觉得q个已经出了我q篇文章的讨围了?/p>

   那么Q我之前有个错误的认识,是认ؓ指向那块内存的指针不移到那块内存中的哪个位|都可以释放那块内存Q但是,q是大错牚wQ释放是不可以释放一部分 的!首先q点应该要明白。而且Q从free()的源代码看,ptr只能指向可用I间的首地址Q不Ӟ减去l构体大之后一定不是指向管理信息空间的首地 址。所以,要确保指针指向可用空间的首地址Q不信吗Q自己可以写一个程序然后移动指向可用空间的指针Q看E序会有会崩Q?/p>

   最后可能想到malloc()的源代码看看malloc()到底是怎么分配I间的,q里面涉及到很多其他斚w的知识!有兴的朋友可以自己M载源
代码ȝ看?/p>


四、关于其他:

    关于C中的malloc()和free()的讨论就写到q里吧!写了三个钟头Q感觉有点篏Q希望对大家有所帮助Q有不对的地Ҏq大家指?br>

isabc 2008-03-22 21:49 发表评论
]]>
mfc框架l合sdk的学习笔?一) [转]http://www.shnenglu.com/Lee7/archive/2008/02/20/43014.htmlisabcisabcWed, 20 Feb 2008 14:47:00 GMThttp://www.shnenglu.com/Lee7/archive/2008/02/20/43014.htmlhttp://www.shnenglu.com/Lee7/comments/43014.htmlhttp://www.shnenglu.com/Lee7/archive/2008/02/20/43014.html#Feedback0http://www.shnenglu.com/Lee7/comments/commentRss/43014.htmlhttp://www.shnenglu.com/Lee7/services/trackbacks/43014.html阅读全文

isabc 2008-02-20 22:47 发表评论
]]>
C/C++中回调函数初?/title><link>http://www.shnenglu.com/Lee7/archive/2008/02/18/42908.html</link><dc:creator>isabc</dc:creator><author>isabc</author><pubDate>Mon, 18 Feb 2008 12:35:00 GMT</pubDate><guid>http://www.shnenglu.com/Lee7/archive/2008/02/18/42908.html</guid><wfw:comment>http://www.shnenglu.com/Lee7/comments/42908.html</wfw:comment><comments>http://www.shnenglu.com/Lee7/archive/2008/02/18/42908.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Lee7/comments/commentRss/42908.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Lee7/services/trackbacks/42908.html</trackback:ping><description><![CDATA[     摘要: 对于很多初学者来_往往觉得回调函数很神U,很想知道回调函数的工作原理。本文将要解释什么是回调函数、它们有什么好处、ؓ什么要使用它们{等问题Q在开始之前,假设你已l熟知了函数指针  <a href='http://www.shnenglu.com/Lee7/archive/2008/02/18/42908.html'>阅读全文</a><img src ="http://www.shnenglu.com/Lee7/aggbug/42908.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Lee7/" target="_blank">isabc</a> 2008-02-18 20:35 <a href="http://www.shnenglu.com/Lee7/archive/2008/02/18/42908.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>IP地址转换函数Q?/title><link>http://www.shnenglu.com/Lee7/archive/2008/01/28/42027.html</link><dc:creator>isabc</dc:creator><author>isabc</author><pubDate>Mon, 28 Jan 2008 06:32:00 GMT</pubDate><guid>http://www.shnenglu.com/Lee7/archive/2008/01/28/42027.html</guid><wfw:comment>http://www.shnenglu.com/Lee7/comments/42027.html</wfw:comment><comments>http://www.shnenglu.com/Lee7/archive/2008/01/28/42027.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/Lee7/comments/commentRss/42027.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/Lee7/services/trackbacks/42027.html</trackback:ping><description><![CDATA[  <p style="FONT-SIZE: 14pt"><font size=6>IP地址转换函数Q?/font></p> <font size=+2> <blockquote> <p style="FONT-SIZE: 14pt">unsigned long inet_addr (const char *cp);</p> <blockquote> <p style="FONT-SIZE: 14pt">inet_addr一个点分十q制IP地址字符串{换成32位数字表C的IP地址Q网l字节顺序)?/p> </blockquote> <p style="FONT-SIZE: 14pt">   </p> <p style="FONT-SIZE: 14pt">char* inet_ntoa (struct in_addr in);</p> <blockquote> <p style="FONT-SIZE: 14pt">inet_ntoa一?2位数字表C的IP地址转换成点分十q制IP地址字符丌Ӏ?/p> </blockquote> <p style="FONT-SIZE: 14pt"> </p> <p style="FONT-SIZE: 14pt">q两个函C为反函数</p> </blockquote></font> <p style="FONT-SIZE: 14pt">   </p> <p style="FONT-SIZE: 14pt"> </p> <p style="FONT-SIZE: 14pt"><font size=6>字节序转换</font></p> <font size=+2> <blockquote> <p style="FONT-SIZE: 14pt">htons()--"Host to Network Short"</p> <p style="FONT-SIZE: 14pt">htonl()--"Host to Network Long"</p> <p style="FONT-SIZE: 14pt">ntohs()--"Network to Host Short"</p> <p style="FONT-SIZE: 14pt">ntohl()--"Network to Host Long"</p> *注意:在你的数据放到网l上的时候,信它是|络字节序<br>|络字节序(大端字节)和x86机器字节序(端字节)<br>eg:0X3132  在x86上显C?1  在网l传输中?2<br></blockquote></font> <img src ="http://www.shnenglu.com/Lee7/aggbug/42027.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/Lee7/" target="_blank">isabc</a> 2008-01-28 14:32 <a href="http://www.shnenglu.com/Lee7/archive/2008/01/28/42027.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++中的错误处理http://www.shnenglu.com/Lee7/archive/2008/01/26/41932.htmlisabcisabcSat, 26 Jan 2008 03:31:00 GMThttp://www.shnenglu.com/Lee7/archive/2008/01/26/41932.htmlhttp://www.shnenglu.com/Lee7/comments/41932.htmlhttp://www.shnenglu.com/Lee7/archive/2008/01/26/41932.html#Feedback0http://www.shnenglu.com/Lee7/comments/commentRss/41932.htmlhttp://www.shnenglu.com/Lee7/services/trackbacks/41932.html阅读全文

isabc 2008-01-26 11:31 发表评论
]]>
þƵ6| ŷ޾þþþƷ| þùƷ| ŷƷž99þڹۿ| ޹Ʒһþ| ձƬҹþ| þùѾƷ| ɫ8þ97㽶987| AVպAVþ| ڵСþþþþþ| þٸ۲AV| þþƷ2020| þѾƷav | ھƷþþþþ99| ƷëٸAVѾþ | AVպAVþþ| ŷþþXXX| þþƷҹƬ| þþþþþAv| ó˾þAvѸ| Ʒþ߹ۿ| 91Ըߺþþþ| ˾ҹվھƷþþþþþþ| þùҹaӰԺ| ҹҹþݺ| ɫۺϾþ| ޵һƷƷþ | ˾þۺߴý| ۺۺϾþ69| պAVëƬƷþþ| ɫ͵͵͵þ˴ý| þþž޾Ʒ| þùAVJUST鶹| þùƷHDAV| þþ99ƷƬĻ| 99þùۺ| AAƬѿƵþ| þˬˬƬAV| Ʒþþþþר| Ʒþþþþ| 97Ʒ˾þþô߽97|