<?xml version="1.0" encoding="gb2312"?>

<!-- RSS generated by oioj.net on 4/16/2004 ; 感谢LeXRus提供 RSS 2.0 文档; 此文件可自由使用，但请保留此行信息 --> 
<!-- Source download URL: http://blogger.org.cn/blog/rss2.asp       -->
<rss version="2.0">

<channel>
<title>sccwqiang的博客</title>
<link>http://blogger.org.cn/blog/blog.asp?name=sccwqiang</link>
<description>sccwqiang的博客</description>
<copyright>blogger.org.cn</copyright>
<generator>W3CHINA Blog</generator>
<webMaster>webmaster@blogger.org.cn</webMaster>
<item>
<title><![CDATA[练车]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=sccwqiang&amp;id=73326</link>
<author>sccwqiang</author>
<pubDate>2015/1/18 23:36:05</pubDate>
<description><![CDATA[今天练车，听了教练大姐说的经历，恍然大悟，加上我之前对你的伤害和上次看我和另外的女生在一起以及以前你的经历，所以造成你无法忍受这种痛苦，而默默的转移自己爱的位置，其实我自己挺笨拙的，你也好不到那去，一个人憋着默默承受。我每天写些东西，只是想让你安心，不想让你忍受相思之苦，为了这都学会了几个社交软件，花了好些心思，其实这种方法是幼稚的，反是被认为是一个不学无术不能信任的男人。在这种情况下都执着，一来我明白事理后，自己可以做个懂的爱和呵护可靠的男人，当然也有能力一起过上好日子。二来你的出现让我在多方面都有了一个正确的认识以及一些人生感悟，让我忘记不了。三来，我觉得自己上次不知道争取机会，丧失掉了机会，一下冒了个人还咄咄逼人，打电话没人通，发短信没人回，QQ一下有个被拒绝的消息，我当时是彻底绝望了，我真的很爱你。]]></description>
</item><item>
<title><![CDATA[今天是2011年07月02号]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=sccwqiang&amp;id=51618</link>
<author>sccwqiang</author>
<pubDate>2011/7/3 1:02:07</pubDate>
<description><![CDATA[今天是到合生元两个多月的时候，回想起这3年来的点点滴滴，不得不说，自己又长成熟了，认识了更多的世界，当时没有考研，而去做开发的事情，我现在没话说，因为以当时的状况很难去考研的，而且又有盛大这么一个公司，所以觉得当时的选择放弃考研是可以的。现在才发现&#160;经验对我的作用真的好大啊，我现在就差这东西啊，哎，不管怎样还是去和他们的争争再说，我不怕你们的。反正比你们要年青点，而且某些方面俺比你们强多了，谦虚谦虚。在次看到三年前写的日子，真的很感动，谢谢，3WChina!!!]]></description>
</item><item>
<title><![CDATA[温馨]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=sccwqiang&amp;id=50816</link>
<author>sccwqiang</author>
<pubDate>2011/1/2 8:11:37</pubDate>
<description><![CDATA[今天天气阴冷，远处工地阵阵作业声，不绝于耳，再次来到这个博客，两字感觉：温馨。]]></description>
</item><item>
<title><![CDATA[CInternetSession 类]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=sccwqiang&amp;id=46781</link>
<author>sccwqiang</author>
<pubDate>2009/8/5 17:49:43</pubDate>
<description><![CDATA[<DIV class=articleTitle>
<DIV style="DISPLAY: inline"><FONT color=#7a6736 size=5 face=微软雅黑>CInternetSession&nbsp;类</FONT></DIV></DIV>
<DIV class=articleTag><FONT size=4><BR></FONT>
<TABLE cellPadding=0>
<TBODY>
<TR>
<TD><A href="mk:@MSITStore:H:/C++%20Language%20Book/VC++/MFC%E7%B1%BB%E5%BA%93%E8%AF%A6%E8%A7%A3.chm::/Class/CObject.htm"><FONT style="BACKGROUND-COLOR: silver" color=#7a6736>CObject</FONT></A></TD></TR>
<TR>
<TD>&nbsp;<WBR>└<FONT style="BACKGROUND-COLOR: silver">CInternetSession</FONT></TD></TR></TBODY></TABLE><BR>使用类CInternetSession 创建并初始化一个或多个同时的Internet 会话。如果需要，还可描述与代理服务器的连接。如果Internet连接必须在应用过程中保持着，可创建一个类CWinApp的CInternetSession成员。一旦已建立起Internet 会话，就可调用OpenURL。CInternetSession会通过调用全局函数AfxParseURL来为分析映射URL。无论协议类型如何，CInternetSession 解释URL并管理它。它可处理由URL资源“file://”标志的本地文件的请求。如果传给它的名字是本地文件，OpenURL 将返回一个指向CStdioFile对象的指针。<BR>如果使用OpenURL在Internet服务器上打开一个URL，你可从此处读取信息。如果要执行定位在服务器上的指定的服务(例如，HTTP，FTP或Gopher)行为，必须与此服务器建立适当的连接。直接打开与指定的服务器的指定的类型的连接，请使用下列成员函数： 
<TABLE cellSpacing=0 cellPadding=2>
<TBODY>
<TR vAlign=top>
<TD>·GetGopherConnection</TD>
<TD>打开与Gopher服务的连接。</TD></TR>
<TR vAlign=top>
<TD>·GetHttpConnection</TD>
<TD>打开与HTTP服务的连接。</TD></TR>
<TR vAlign=top>
<TD>·GetFtpConnection</TD>
<TD>打开与FTP服务的连接。</TD></TR></TBODY></TABLE>QueryOption和SetOption允许设置会话的查询选项，如超时值、再试次数等等。<BR>Internet会话过程中，象查找或数据下载这样的事务处理会占用一定的时间。使用者可能想继续工作，或获得事务处理进程的状态信息。为解决这个问题，CInternetSession可以让查找和数据传输异步发生，允许使用者在传输结束时进行其它任务。如果要为使用者提供状态信息，或异步处理任意操作，必须设置三个条件： 
<TABLE cellSpacing=0 cellPadding=2>
<TBODY>
<TR vAlign=top>
<TD>·</TD>
<TD>在构造函数中，dwFlags必须包括INTERNET_FLAG_ASYNC。</TD></TR>
<TR vAlign=top>
<TD>·</TD>
<TD>在构造函数中，dwContext必须设置为1。</TD></TR>
<TR vAlign=top>
<TD>·</TD>
<TD>必须通过调用EnableStatusCallback来建立回调函数。</TD></TR></TBODY></TABLE>使用覆盖成员函数OnStatusCallback来获得异步获取的状态信息。使用此覆盖成员函数，必须从CInternetSession派生你自己的类。<BR>要了解异步操作的更多信息，请参阅联机文档“Visual C++程序员指南”中的“Internet初步：WinInet”。要了解使用MFC WinInet 类的一般信息，请参阅联机文档“Visual C++程序员指南”中的“使用WinInet编写Internet程序”。<BR>注意：<BR>CInternetSession将为不支持的服务类型产生一个AfxThrowNotSupportedExce<WBR>ption。当前只支持下列服务类型：FTP，HTTP，Gopher和文件。<BR>头文件 :#include &lt;afxinet.h&gt;<BR></DIV>]]></description>
</item><item>
<title><![CDATA[CHttpFile实现Get/Post]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=sccwqiang&amp;id=46780</link>
<author>sccwqiang</author>
<pubDate>2009/8/5 17:42:42</pubDate>
<description><![CDATA[<P><FONT color=#ff0000 size=6><STRONG>CHttpFile实现Get/Post</STRONG></FONT></P>
<P>一、GET 数据，下载网页，文件等，用于可下载的文件，不能用于服务端运行的程序，比如.aspx文件等，否则会返回500错误。</P>
<P>CString strSentence, strWriteName="1.htm";<BR>&nbsp;&nbsp;&nbsp; CString strFileName="<A href="http://localhost/InDesign/">http://localhost/InDesign/</A>" + strWriteName;</P>
<P>&nbsp;&nbsp;&nbsp; CInternetSession sess;<BR>&nbsp;&nbsp;&nbsp; CHttpFile* fileGet;<BR>&nbsp;&nbsp;&nbsp; try<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fileGet=(CHttpFile*)sess.OpenURL(strFileName);<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; catch(CException* e)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fileGet = 0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw;<BR>&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; </P>
<P>&nbsp;&nbsp;&nbsp; if(fileGet)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwStatus;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwBuffLen = sizeof(dwStatus);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BOOL bSuccess = fileGet-&gt;QueryInfo(HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &amp;dwStatus, &amp;dwBuffLen);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( bSuccess &amp;&amp; dwStatus&gt;= 200&amp;&amp; dwStatus&lt;300 ) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CStdioFile fileWrite; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(fileWrite.Open(strWriteName, CFile::modeWrite|CFile::modeCreate))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(fileGet-&gt;ReadString(strSentence))<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fileWrite.WriteString(strSentence+"\n");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fileWrite.Close();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AfxMessageBox("下载完毕");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AfxMessageBox("本地文件"+strWriteName+"打开出错."); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strSentence.Format("打开网页文件出错，错误码：%d", dwStatus);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AfxMessageBox(strSentence);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fileGet-&gt;Close();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete fileGet;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AfxMessageBox("不能找到网页文件！");</P>
<P>&nbsp;&nbsp;&nbsp; sess.Close();</P>
<P>二、POST 数据，比如用于提交注册信息等</P>
<P>CString strHttpName="<A href="http://localhost/TestReg/RegForm.aspx">http://localhost/TestReg/RegForm.aspx</A>"; // 需要提交数据的页面<BR>&nbsp;&nbsp;&nbsp; CString strFormData = "username=abc&amp;password=123";&nbsp;&nbsp;&nbsp; // 需要提交的数据</P>
<P>&nbsp;&nbsp;&nbsp; CInternetSession sess;<BR>&nbsp;&nbsp;&nbsp; CHttpFile* fileGet;<BR>&nbsp;&nbsp;&nbsp; CString strHeaders = _T("Content-Type: application/x-www-form-urlencoded"); // 请求头</P>
<P>&nbsp;&nbsp;&nbsp; try<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fileGet=(CHttpFile*)sess.OpenURL(strHttpName);//打开文件<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; catch(CException* e)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fileGet = 0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw;<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; CString strSentence, strGetSentence = "";<BR>&nbsp;&nbsp;&nbsp; if(fileGet)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwStatus;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DWORD dwBuffLen = sizeof(dwStatus);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BOOL bSuccess = fileGet-&gt;QueryInfo(HTTP_QUERY_STATUS_CODE|HTTP_QUERY_FLAG_NUMBER, &amp;dwStatus, &amp;dwBuffLen);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( bSuccess &amp;&amp; dwStatus&gt;= 200 &amp;&amp;dwStatus&lt;300 )<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BOOL result = fileGet-&gt;SendRequest(strHeaders, (LPVOID)(LPCTSTR)strFormData, strFormData.GetLength());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(fileGet-&gt;ReadString(strSentence))&nbsp;&nbsp;&nbsp; // 读取提交数据后的返回结果<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strGetSentence = strGetSentence + strSentence + char(13) + char(10);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AfxMessageBox(strGetSentence); // 显示返回网页内容<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strSentence.Format("POST出错，错误码：%d", dwStatus);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AfxMessageBox(strSentence);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fileGet-&gt;Close();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delete fileGet;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AfxMessageBox("不能找到网页文件！");</P>
<P>&nbsp;&nbsp;&nbsp; sess.Close();</P>
<P>&nbsp;</P>
<P>补充:&nbsp; void&nbsp;&nbsp; xx(void)&nbsp;&nbsp; <BR>&nbsp; {&nbsp;&nbsp; <BR>&nbsp; CHAR&nbsp;&nbsp; szReceiveBuffer[36000];&nbsp;&nbsp; <BR>&nbsp; memset(szReceiveBuffer,0,36000);&nbsp;&nbsp; <BR>&nbsp; char&nbsp;&nbsp; *req="POST&nbsp;&nbsp; HTTP/1.0\r\n"&nbsp;&nbsp; <BR>&nbsp; "Accept:&nbsp;&nbsp; image/gif,&nbsp;&nbsp; image/x-xbitmap,&nbsp;&nbsp; image/jpeg,&nbsp;&nbsp; image/pjpeg,&nbsp;&nbsp; application/vnd.ms-excel,&nbsp;&nbsp; application/msword,&nbsp;&nbsp; application/vnd.ms-powerpoint,&nbsp;&nbsp; */*\r\n"&nbsp;&nbsp; <BR>&nbsp; "Accept-Language:&nbsp;&nbsp; en-us\r\n"&nbsp;&nbsp; <BR>&nbsp; "Accept-Encoding:&nbsp;&nbsp; gzip,&nbsp;&nbsp; deflate\r\n"&nbsp;&nbsp; <BR>&nbsp; "User-Agent:&nbsp;&nbsp; Mozilla/4.0\r\n"&nbsp;&nbsp; <BR>&nbsp; "Content-Length:&nbsp;&nbsp; 34\r\n"&nbsp;&nbsp; <BR>&nbsp; "Host:&nbsp;&nbsp; 127.0.0.1\r\n"&nbsp;&nbsp; <BR>&nbsp; "Content-Type:&nbsp;&nbsp; application/x-www-form-urlencoded\r\n\r\n";&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp; LPSTR&nbsp;&nbsp; lpOptions="user=admin&amp;Pwd=admin&amp;submit=提交";&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp; CInternetSession&nbsp;&nbsp; cInternetSession;&nbsp;&nbsp; <BR>&nbsp; CHttpConnection&nbsp;&nbsp; *&nbsp;&nbsp; pHttpConnection&nbsp;&nbsp; =&nbsp;&nbsp; cInternetSession.GetHttpConnection(_T("127.0.0.1"),&nbsp;&nbsp; (INTERNET_PORT)80);&nbsp;&nbsp; <BR>&nbsp; CHttpFile&nbsp;&nbsp; *&nbsp;&nbsp; pHttpFile&nbsp;&nbsp; =&nbsp;&nbsp; pHttpConnection-&gt;OpenRequest("POST",&nbsp;&nbsp; _T("/admin/test.asp"));&nbsp;&nbsp; <BR>&nbsp; pHttpFile-&gt;AddRequestHeaders(req);&nbsp;&nbsp; <BR>&nbsp; pHttpFile-&gt;SendRequest(0,0,&nbsp;&nbsp; (LPVOID)&nbsp;&nbsp; lpOptions,&nbsp;&nbsp; (DWORD)strlen(lpOptions));&nbsp;&nbsp; <BR>&nbsp; pHttpFile-&gt;Read(szReceiveBuffer,&nbsp;&nbsp; 36000);&nbsp;&nbsp; <BR>&nbsp; cInternetSession.Close();&nbsp;&nbsp; <BR>&nbsp; //CString&nbsp;&nbsp; hh=szReceiveBuffer;&nbsp;&nbsp; <BR>&nbsp; //if(hh.Find("您输入了错误的帐号或",0))&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox(szReceiveBuffer);&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp; return&nbsp;&nbsp; ;&nbsp;&nbsp; <BR>&nbsp; }&nbsp;&nbsp; </P>
<P>本文来自CSDN博客，转载请标明出处：<A href="http://blog.csdn.net/taixi1268/archive/2009/04/13/4069881.aspx">http://blog.csdn.net/taixi1268/archive/2009/04/13/4069881.aspx</A></P>]]></description>
</item><item>
<title><![CDATA[在MFC中加一个控制台DOS界面]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=sccwqiang&amp;id=46779</link>
<author>sccwqiang</author>
<pubDate>2009/8/5 16:59:14</pubDate>
<description><![CDATA[
<P>//****************************************************************//</P>
<P>如下，如是对话框程序的话，只要把我这段代码拷贝到OnInitDialog中就可以了，当然ConsoleHandler是全局的了.如果是文档程序的话，C**App::InitInstance中就OK。<BR>BOOL CMFCAPPDlg::OnInitDialog()<BR>{<BR>&nbsp;//**************************************//<BR>&nbsp;BOOL bTest = AllocConsole();<BR>&nbsp;if(!bTest)<BR>&nbsp;{<BR>&nbsp;&nbsp;::MessageBox(NULL,"ERROR AllocConsole",TEXT(""),MB_OK);<BR>&nbsp;}<BR>&nbsp;AllocConsole();&nbsp;// you only get 1 console.<BR>&nbsp;<BR>&nbsp;DWORD astds[3]={STD_OUTPUT_HANDLE,STD_ERROR_HANDLE,STD_INPUT_HANDLE};<BR>&nbsp;FILE *atrgs[3]={stdout,stderr,stdin};<BR>&nbsp;for( register int i=0; i&lt;3; i++ ) <BR>&nbsp;{<BR>&nbsp;&nbsp;long hand=(long)GetStdHandle(astds[i]);<BR>&nbsp;&nbsp;if( hand!=(long)INVALID_HANDLE_VALUE ) <BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;int osf=_open_osfhandle(hand,_O_TEXT);<BR>&nbsp;&nbsp;&nbsp;if( osf!=-1 ) <BR>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;FILE *fp=_fdopen(osf,(astds[i]==STD_INPUT_HANDLE) ? "r" : "w");<BR>&nbsp;&nbsp;&nbsp;&nbsp;if( fp!=NULL ) <BR>&nbsp;&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*(atrgs[i])=*fp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setvbuf(fp,NULL,_IONBF,0);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;}</P>
<P>&nbsp;&nbsp; SetConsoleCtrlHandler((PHANDLER_ROUTINE)ConsoleHandler, TRUE);<BR>&nbsp;}</P>
<P>ConsoleHandler控制台界面接收事件的用的。比如说CTRL + C，此时，这个回调函数就会得到此消息，你就可以在这里进行相关的处理了。这很好用的，特别是有时候你调试时候，想要拥有WIN32 Consele下的那种命令操作符：</P>
<P>BOOL WINAPI ConsoleHandler(DWORD CEvent)</P>
<P>{<BR>&nbsp;&nbsp;&nbsp; switch(CEvent)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp; case CTRL_C_EVENT:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox(NULL,"CTRL + C received!", "signal", MB_OK);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>&nbsp;&nbsp;&nbsp; case CTRL_BREAK_EVENT:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox(NULL,"CTRL+BREAK received!", "signal", MB_OK);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>&nbsp;&nbsp;&nbsp; case CTRL_CLOSE_EVENT:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox(NULL,"Program being closed!", "signal", MB_OK);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>&nbsp;&nbsp;&nbsp; case CTRL_LOGOFF_EVENT:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox(NULL, "User is logging off!", "signal", MB_OK);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>&nbsp;&nbsp;&nbsp; case CTRL_SHUTDOWN_EVENT:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MessageBox(NULL,"User is logging off!", "signal", MB_OK);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; return TRUE;<BR>}<BR>&nbsp;&nbsp;// Main message loop:<BR>&nbsp;<BR>&nbsp;//**************************************//</P>
<P>｝</P>
<P>最后说一下，ConsoleHandler应该拿到最上面去，不然，会报错的。</P>]]></description>
</item><item>
<title><![CDATA[strtol 函数]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=sccwqiang&amp;id=46778</link>
<author>sccwqiang</author>
<pubDate>2009/8/5 11:11:28</pubDate>
<description><![CDATA[<A>strtol()这个函数(转)</A>
<P><FONT size=3>今天，在review 一些代码的时候，看到了strtol()这个函数，由于以前使用它的时候，还没有深刻的了解，这次，我决定探个究竟。</FONT></P>
<P><FONT size=3>网上关于这个函数的资料大都来源于同份资料，linux库函数，讲的不够细致。于是，我花了几个小时，认真地尝试其功能，并整理了这篇文章，希望能对C语言的爱好者一些帮助。</FONT></P>
<P><FONT size=3>希望大家能够将本文中发现的错误及时反馈给我，以便修正。</FONT></P>
<P><FONT size=3>+----------------+<BR>|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; strtol&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |<BR>+----------------+</FONT></P>
<P><FONT size=3>i.e. string to long</FONT></P>
<P><FONT size=3>long int strtol(const char *nptr, char **endptr, int base)<BR>strtol()会将nptr指向的字符串，根据参数base，按权转化为long int, 然后返回这个值。<BR>参数base的范围为2~36,和0；它决定了字符串以被转换为整数的权值。<BR>可以被转换的合法字符依据base而定，举例来说，当base为2时，合法字符为‘0’，‘1’；base为8时，合法字符为‘0’，‘1’，……‘7’；base为10时，合</FONT><FONT size=3>法字符为‘0’，‘1’，……‘9’；base 为16时，合法字符为‘0’，‘1’，……‘9’，‘a’，……‘f’；base为24时，合法字符为‘0’，……‘9’，‘a’，……‘n’，base</FONT><FONT size=3>为36时，合法字符为‘0’，……‘9’，‘a’，……‘z’；等等。其中，不区分大小写，比如，‘A’和‘a’会都会被转化为10。<BR>当字符合法时，‘0’，……‘9’依次被转换为十进制的0～9，‘a’，……‘z’一次北转换为十进制的10～35。<BR>strtol()函数检测到第一个非法字符时，立即停止检测，其后的所有字符都会被当作非法字符处理。合法字符串会被转换为long int, 作为函数的返</FONT><FONT size=3>回值。非法字符串，即从第一个非法字符的地址，被赋给*endptr。**endptr是个双重指针，即指针的指针。strtol()函数就是通过它改变*endptr的值，即把第一个非法字符的地址传给endptr。</FONT></P>
<P><FONT size=3>多数情况下，endptr设置为NULL, 即不返回非法字符串。<BR>下面看几个例子:<BR>------------------------------------------------------<BR>char buffer[20]="10379cend$3";<BR>char *stop;<BR>printf("%d\n",strtol(buffer, &amp;stop, 2));<BR>printf("%s\n", stop);<BR>输出结果：<BR>2<BR>379cend$3<BR>-------------------------------------------------------<BR>char buffer[20]="10379cend$3";<BR>char *stop;<BR>printf("%d\n",strtol(buffer, &amp;stop, 8));<BR>printf("%s\n", stop);<BR>输出结果：<BR>543<BR>9cend$3<BR>--------------------------------------------------------<BR>char buffer[20]="10379cend$3";<BR>char *stop;<BR>printf("%d\n",strtol(buffer, &amp;stop, 10));<BR>printf("%s\n", stop);<BR>输出结果：<BR>10379<BR>cend$3<BR>-------------------------------------------------------<BR>char buffer[20]="10379cend$3";<BR>char *stop;<BR>printf("%d\n",strtol(buffer, &amp;stop, 16));<BR>printf("%s\n", stop);<BR>输出结果：<BR>17005006<BR>nd$3<BR>另外，如果base为0，且字符串不是以0x(或者0X)开头，则按十进制进行转化。如果base为0或者16，并且字符串以0x（或者0X）开头，那么，x（</FONT><FONT size=3>或者X）被忽略，字符串按16进制转化。如果base不等于0和16，并且字符串以0x(或者0X)开头，那么x被视为非法字符。<BR>例如:<BR>-------------------------------------------------------<BR>char buffer[20]="0x31da6c";<BR>char *stop;<BR>printf("%d\n",strtol(buffer, &amp;stop, 0));<BR>printf("%s\n", stop);<BR>输出结果(stop为空)：<BR>3267180</FONT></P>
<P><FONT size=3>-------------------------------------------------------<BR>char buffer[20]="0x31da6c";<BR>char *stop;<BR>printf("%d\n",strtol(buffer, &amp;stop, 13));<BR>printf("%s\n", stop);<BR>输出结果：<BR>0<BR>0x31da6c<BR>-------------------------------------------------------</FONT></P>
<P><FONT size=3>最后，需要说明的是，对于nptr指向的字符串，其开头和结尾处的空格被忽视，字符串中间的空格被视为非法字符。<BR>例如：<BR>-------------------------------------------------------<BR>char buffer_1[20]="10379c";<BR>char buffer_2[20]="&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10379c&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ";<BR>char buffer_3[20]="&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 379c&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ";<BR>printf("%d\n",strtol(buffer_1,NULL,0));<BR>printf("%d\n",strtol(buffer_2,NULL,0));<BR>printf("%d\n",strtol(buffer_3,NULL,0));<BR>输出结果为：<BR>10379<BR>10379<BR>10<BR>--------------------------------------------------------</FONT></P>]]></description>
</item><item>
<title><![CDATA[outputParam]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=sccwqiang&amp;id=46643</link>
<author>sccwqiang</author>
<pubDate>2009/7/23 11:56:33</pubDate>
<description><![CDATA[<P>再来一个关于OUTPUT的</P>
<P>int CAppDatabase::GetMenuContent(int & iOperator,const CString &strMenuId, CMoInfo &moInfo, CString &strMenu, CString &strSubID)<BR>{<BR>&#160;if ( !OpenDB() )<BR>&#160;{<BR>&#160;&#160;return false;<BR>&#160;}<BR>&#160;try<BR>&#160;{<BR>&#160;&#160;_CommandPtr pCmd;<BR>&#160;&#160;_ParameterPtr pParam;<BR>&#160;&#160;_RecordsetPtr pRs;<BR>&#160;&#160;pParam.CreateInstance(__uuidof(Parameter));<BR>&#160;&#160;pCmd.CreateInstance(__uuidof(Command));<BR>&#160;&#160;<BR>&#160;&#160;&#160;&#160;&#160;&#160;&#160; pCmd->ActiveConnection = m_pConn;<BR>&#160;&#160;pCmd->CommandType = adCmdStoredProc;<BR>&#160;&#160;&#160;&#160;&#160;&#160;&#160; pCmd->PutPrepared(true);&#160;&#160;&#160;&#160;&#160;&#160; <BR>&#160;&#160;int te =0;<BR>&#160;&#160;pCmd->CommandText = _bstr_t("DP_SMS_GetUniteMenu2");<BR>&#160;&#160;/*&#160;p_sSubID&#160;&#160;&#160; out varchar2, --对应yyruser.yyr_uniform_menus中的subid<BR>&#160;&#160;&#160;p_sContents out varchar2, --菜单内容<BR>&#160;&#160;&#160;p_nReturn&#160;&#160; out number&#160; -- 返回值，1 成功，0失败或没找到菜单*/<BR>&#160;&#160;pParam = pCmd->CreateParameter(_bstr_t("p_sBaseServiceCode"), adVarChar, adParamInput, 21, _variant_t(_bstr_t(moInfo.SmsMoInfo.strBaseServiceCode)));<BR>&#160;&#160;pCmd->Parameters->Append(pParam);<BR>&#160;&#160;pParam = pCmd->CreateParameter(_bstr_t("p_sMenuID"), adVarChar, adParamInput, 21, _variant_t(_bstr_t(strMenuId)));<BR>&#160;&#160;pCmd->Parameters->Append(pParam);<BR>&#160;&#160;pParam = pCmd->CreateParameter(_bstr_t("p_sSource"), adVarChar, adParamInput, 10, _variant_t(_bstr_t(moInfo.strPlatformID)));<BR>&#160;&#160;pCmd->Parameters->Append(pParam);<BR>&#160;&#160;pParam = pCmd->CreateParameter(_bstr_t("p_nOperator"), adInteger, adParamInput, 4, _variant_t(_bstr_t(long(iOperator))));<BR>&#160;&#160;pCmd->Parameters->Append(pParam);</P>
<P>&#160;&#160;pParam = pCmd->CreateParameter(_bstr_t("p_sProvince"), adVarChar, adParamInput, 21, _variant_t(_bstr_t(moInfo.SmsMoInfo.strSrcProvince)));<BR>&#160;&#160;pCmd->Parameters->Append(pParam);<BR>&#160;&#160;pParam = pCmd->CreateParameter(_bstr_t("p_sCity"), adVarChar, adParamInput, 21, _variant_t(_bstr_t(moInfo.SmsMoInfo.strSrcCity)));<BR>&#160;&#160;pCmd->Parameters->Append(pParam);<BR>&#160;<BR>&#160;&#160;pParam = pCmd->CreateParameter(_bstr_t("p_sSubID"), adVarChar, adParamOutput, 100, _variant_t(_bstr_t(strSubID)));<BR>&#160;&#160;pCmd->Parameters->Append(pParam);<BR>&#160;&#160;pParam = pCmd->CreateParameter(_bstr_t("p_sContents"), adVarChar, adParamOutput, 100, _variant_t(_bstr_t(strMenu)));<BR>&#160;&#160;pCmd->Parameters->Append(pParam);<BR>&#160;&#160;pParam = pCmd->CreateParameter(_bstr_t("p_iResult"), adInteger, adParamOutput, 1, _variant_t(long(te)));<BR>&#160;&#160;pCmd->Parameters->Append(pParam);<BR>&#160;&#160;<BR>&#160;&#160;pRs = pCmd->Execute(NULL, NULL, adCmdStoredProc);<BR>&#160;&#160;<BR>&#160;&#160;strSubID = (char*)_bstr_t(pCmd->Parameters->GetItem(_variant_t("p_sSubID"))->Value);//g_AppDB.GetValueStr(pRs,_variant_t ("p_sContents"));<BR>&#160;&#160;strMenu = (char*)_bstr_t(pCmd->Parameters->GetItem(_variant_t("p_sContents"))->Value);<BR>&#160;&#160;<BR>&#160;&#160;int nRet = pCmd->Parameters->GetItem(_variant_t("p_iResult"))->Value.intVal;<BR>&#160;&#160;<BR>&#160;&#160;if (adStateClosed != pRs->GetState())<BR>&#160;&#160;{<BR>&#160;&#160;&#160;pRs->Close();<BR>&#160;&#160;}<BR>&#160;&#160;pRs.Release();<BR>&#160;&#160;pParam.Release();<BR>&#160;&#160;pCmd.Release();<BR>&#160;}<BR>&#160;catch (_com_error& e) <BR>&#160;{<BR>&#160;&#160;m_bConn = false;<BR>&#160;&#160;MessageBox(NULL,e.ErrorMessage(),"T",MB_OK);<BR>&#160;&#160;DMPcomERR(e);<BR>&#160;&#160;return false;<BR>&#160;} catch(...) { <BR>&#160;&#160;WriteLog(g_Log, "类CAppDatabase中的函数AddTest异常");<BR>&#160;&#160;return false;&#160;<BR>&#160;}<BR>&#160;return true;&#160;<BR>}</P>]]></description>
</item><item>
<title><![CDATA[有关CTime和ColeDateTime]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=sccwqiang&amp;id=46504</link>
<author>sccwqiang</author>
<pubDate>2009/7/12 15:47:59</pubDate>
<description><![CDATA[
<DIV class=tit><FONT color=#ff3300 size=5><STRONG>[转]有关CTime和ColeDateTime</STRONG></FONT> </DIV>
<TABLE style="TABLE-LAYOUT: fixed">
<TBODY>
<TR>
<TD>
<DIV id=blog_text class=cnt>1、通用处理：time_t（win平台64位系列对应__time64_t,Linux暂无研究，以后补上）<BR>time_t＝long int，范围从1970－1－1 0:0:0 到2038－1－18 19:14:07<BR>__time64_t＝__int64，范围从1970－1－1 0:0:0 到3000－12－31 23:59:59<BR>这个变量每一秒增加1，精度很低。但是已经可以处理常用时间问题了：<BR><WBR></WBR><WBR></WBR>A、获取当前时间：<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>time_t ttime=time(NULL);<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>__time64_t ttime=_time64(NULL);<BR><WBR></WBR><WBR></WBR>B、转换time_t到可以识别的结构struct tm：<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>struct tm *ptm=localtime(&amp;ttime);<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>或者 struct tm *ptm=gmtime(&amp;ttime);<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>struct tm *ptm=_localtime64(&amp;ttime);<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>或者 struct tm *ptm=_gmtime64(&amp;ttime);<BR><WBR></WBR><WBR></WBR>C、获取时间差：<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>double difftime(time_t tm1,time_t tm2);<BR><WBR></WBR><WBR></WBR>D、创建：<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>time_t mktime(struct tm*ptm);<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>__time64_t _mktime64(struct tm*ptm);<BR><WBR></WBR><WBR></WBR>E、拼装字符串：<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>size_t strftime(char*strDest,size_t maxsize,const char*format,const struct tm*timeptr);<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>size_t wcsftime(wchar_t*strDest,size_t maxsize,const wchar_t*format,const struct tm *timeptr);<BR><WBR></WBR><WBR></WBR>说明：<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>time_t时间范围有限，到2038年将面临第2次千年虫危机<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>struct tm结构要注意：tm_year从1900年计数，tm_mon月份从0计数<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>对于struct tm *，由于是栈对象的直接使用，所以一次只能使用一个，即：<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>struct tm *ptm1=_localtime(&amp;ttime1);<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>struct tm *ptm2=_localtime(&amp;ttime2);<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>即使ttime1和ttime2不是一个时间，得到的ptm1也是等于ptm2的！ <WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><BR>2、Win32 Platform SDK：<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>A、SYSTEMTIME结构：<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>void GetSystemTime( LPSYSTEMTIME lpSystemTime);<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>void GetLocalTime(LPSYSTEMTIME lpSystemTime);<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>BOOL SetSystemTime(const SYSTEMTIME* lpSystemTime);<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>B、FILETIME结构（由GetFileTime函数或者FindFirstFile函数获得），与SYSTEMTIME结构相互转换：<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>BOOL FileTimeToSystemTime(const FILETIME* lpFileTime,LPSYSTEMTIME lpSystemTime);<BR>BOOL SystemTimeToFileTime(const SYSTEMTIME* lpSystemTime,LPFILETIME lpFileTime);<BR>3、Win32平台：<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>DWORD GetTickCount(void);<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>计数机器启动至今毫秒数，对于一般精度已经足够表示了。要注意：<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>A、最多只能计数49.7天，如果windows这么长还未重启，计数失效<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>B、这个是以5秒92下的机器计数为基础的，所以精度只能精确到百毫秒，需要更高精度，请看下面：<BR>4、终极精度时间函数：<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>A、win32：<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>LARGE_INTEGER li={0};<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>QueryPerformanceCounter(&amp;li);<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>li.QuadPart返回的是机器计数微妙！<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>B、linux：<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>struct timeval tv={0};<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>struct timezone tz={0};<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>gettimeofday(&amp;tv,&amp;tz);<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>其中tv.tv_sec存储秒信息，tv.tv_usec存储微妙信息<BR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR>C、对于select函数，参数timeval可以精确到微妙等待，本来以为所有平台都会因此有延时功能。实际中却发现，win2000及以下平台居然是精度不够立即返回！造成无间断循环导致CPU 100％！所以跨平台编程时，建议此函数慎用！<BR>5、win32的DATE类型<BR><WBR></WBR><WBR></WBR><WBR></WBR>其实DATE＝double，整数部分保存1900－1－1以来天数，小数部分保存微妙数<BR><WBR></WBR><WBR></WBR><WBR></WBR>可以通过以下函数与SYSTEMTIME相互转换：<BR><WBR></WBR><WBR></WBR><WBR></WBR>INT VariantTimeToSystemTime(double vtime,LPSYSTEMTIME lpSystemTime);<BR><WBR></WBR><WBR></WBR><WBR></WBR>INT SystemTimeToVariantTime(LPSYSTEMTIME lpSystemTime,double*pvtime); <WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><WBR></WBR><BR><WBR></WBR><WBR></WBR><WBR></WBR>也可以通过COleDatetime类进行处理。使用中，COleDatetime便是以此类型作为基础处理，同时ADO数据库编程中，时间字段返回的也是这个类型<BR><WBR></WBR><WBR></WBR><WBR></WBR>但是这两种转换都存在重大数据丢失问题！最终都只能保留到秒信息，毫秒信息没了，而且还对毫秒做了四舍五入运算！<BR><WBR></WBR><WBR></WBR><WBR></WBR>如果是数据库编程设计这种高精度，就不能使用ADO了，只能用ODBC和OLE DB<BR>6、MFC中有两个类：COleDatetime（以DATE为基础），CTime（以__time64_t为基础）<BR><WBR></WBR><WBR></WBR><WBR></WBR>如果绑定的是日期型控件，一定要用COleDatetime！虽然CTime可以精确到3000年，但是超过这个范围，CTime是要抛出异常，让你程序崩溃的！<BR>===================================================<BR>
<DIV class=cnt>
<P>在MFC中操作时间的类主要有两对：CTime和CTimeSpan与 COleDateTime和COleDateTimeSpan，CTime和CTimeSpan主要封装了ANSI time_t和关于time_t的Run-Time库的主要函数，CTime里面使用的成员变量是time_t类型，该类型是个long型，由于long 类型的原因，所以该类只能处理4294967296秒约68年的数据，所以用CTime只能处理1970年到2038年的日期。<BR><WBR></WBR><WBR></WBR><WBR></WBR>幸好，MFC同时提供了COleDateTime和COleDateTimeSpan类，使用该两个类完全可以代替CTime和 CTimeSpan，COleDateTime和COleDateTimeSpan类所使用的成员变量是DATE类型，该类型是个double类型，而且使用的单位是日，所以可以处理从100年1月1日到9999年12月31日的日期时间，COleDateTime类的日期计算主要是操作公有成员变量 COleDateTime::m_dt，该变量是DATE即double类型，该变量是为零时是1899年12月30日0时0分0秒，大于零时的日期比 1899年12月30日0时0分0秒大，反之亦然，例如：<BR>COleDateTime t;<BR>t.m_dt=0;<BR>AfxMessageBox(t.Format("%Y-%m-%d %H:%M:%S"));<BR>运行的结果是：1899-12-30 00:00:00</P>
<P>COleDateTime t;<BR>t.m_dt=39444.437731;<BR>AfxMessageBox(t.Format("%Y-%m-%d %H:%M:%S"));<BR>运行的结果是：2007-10-28 10:30:20</P>
<P>反过来以可以得到变量的值，例如：<BR>COleDateTime t(2004,12,28,22,22,22);<BR>CString str;<BR>str.Format("%f",t.m_dt);<BR>AfxMessageBox(str);<BR>运行的结果是：38349.932199</P>
<P>COleDateTimeSpan类是用于对COleDateTime类的两个时间的时间间隔的计算,COleDateTimeSpan类使用的成员变量COleDateTimeSpan::m_span是一个double类型是用于记录两个COleDateTime::m_dt的时间差，例如：<BR>COleDateTime t1(2006,1,1,0,0,0);<BR>COleDateTime t2(2007,1,1,0,0,0);<BR>COleDateTimeSpan ts=t2-t1;<BR>CString str;<BR>str.Format("%f",ts.m_span);<BR>AfxMessageBox(str);<BR>运行的结果是：365.000000</P>
<P>反过来也可以得到日期<BR>COleDateTime t1(2006,1,1,0,0,0);<BR>COleDateTimeSpan ts;<BR>ts.m_span=400.0;<BR>COleDateTime t2=t1+ts;<BR>AfxMessageBox(t2.Format("%c"));<BR>运行的结果是：02/05/07 00:00:00</P>
<P>可是在使用COleDateTimeSpan类中以下的几个函数可要小心，这不知道是不是MFC的一个Bug，<BR>double GetTotalDays( ) const;<BR>double GetTotalHours( ) const;<BR>double GetTotalMinutes( ) const;<BR>double GetTotalSeconds( ) const;<BR>几个函数的返回值都是double类型<BR>但是，如double GetTotalSeconds( ) const;在MFC内部的原形是：<BR>_AFXDISP_INLINE double COleDateTimeSpan::GetTotalSeconds() const<BR>{ ASSERT(GetStatus() == valid);<BR><WBR></WBR><WBR></WBR>long lReturns = (long)(m_span * 24 * 60 * 60 + AFX_OLE_DATETIME_HALFSECOND);<BR><WBR></WBR><WBR></WBR>return lReturns;<BR>}<BR>看到没有，它返回的实际是个long类型，并不是一个double类型，所以在使用这几个函数的时候计算两个时间的间隔不要太大，特别是 GetTotalSeconds( )函数，如计算两个时间的间隔大于68年时就会溢出，所以我建议直接读取COleDateTimeSpan::m_span变量的值，这是一个单位为日的时间间隔，例如：<BR>COleDateTime t1(2000,1,1,0,0,0);<BR>COleDateTime t2(2070,1,1,0,0,0);<BR>COleDateTimeSpan ts=t2-t1;<BR>CString str;<BR>str.Format("%f",ts.GetTotalSeconds());<BR>AfxMessageBox(str);<BR>运行的结果是：-2085892096.000000<BR>这个结果明显是一个溢出，如果使用<BR>str.Format("%f",ts.m_span*86400);<BR>则会得到2209075200.000000。</P>
<P>所以灵活使用COleDateTime类的m_dt变量和COleDateTimeSpan类的m_span变量操作会得到意想不到的收获</P></DIV></DIV></TD></TR></TBODY></TABLE>]]></description>
</item><item>
<title><![CDATA[variant_t ，_bstr_t 与 CString 类区别]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=sccwqiang&amp;id=46502</link>
<author>sccwqiang</author>
<pubDate>2009/7/12 11:25:26</pubDate>
<description><![CDATA[<STRONG><FONT color=#6699ff>一、其它数据类型转换为字符串</FONT></STRONG> 
<DIV class=postbody>
<DIV class=postbody>
<UL>
<LI><FONT color=#6699ff>短整型(int)</FONT><BR>itoa(i,temp,10);///将i转换为字符串放入temp中,最后一个数字表示十进制<BR>itoa(i,temp,2); ///按二进制方式转换 
<LI><FONT color=#6699ff>长整型(long)</FONT><BR>ltoa(l,temp,10); 
<LI><FONT color=#6699ff>浮点数(float,double)</FONT><BR>用fcvt可以完成转换,这是MSDN中的例子:<BR>int decimal, sign; <BR>char *buffer; <BR>double source = 3.1415926535; <BR>buffer = _fcvt( source, 7, &amp;decimal, &amp;sign ); <BR>运行结果:source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 0<BR>decimal表示小数点的位置,sign表示符号:0为正数，1为负数 
<LI><FONT color=#6699ff>CString变量</FONT><BR>str = "2008北京奥运";<BR>buf = (LPSTR)(LPCTSTR)str; 
<LI><FONT color=#6699ff>BSTR变量</FONT><BR>BSTR <FONT color=#000000><SPAN style="PADDING-BOTTOM: 0pt; BACKGROUND-COLOR: yellow; PADDING-LEFT: 0pt; PADDING-RIGHT: 0pt; DISPLAY: inline; COLOR: black; PADDING-TOP: 0pt">bstrVal</SPAN>u</FONT>e = ::SysAllocString(L"程序员"); <BR>char * buf = _com_util::ConvertBSTRToString(<SPAN style="PADDING-BOTTOM: 0pt; BACKGROUND-COLOR: yellow; PADDING-LEFT: 0pt; PADDING-RIGHT: 0pt; DISPLAY: inline; COLOR: black; PADDING-TOP: 0pt">bstrVal</SPAN>ue); <BR>SysFreeString(<SPAN style="PADDING-BOTTOM: 0pt; BACKGROUND-COLOR: yellow; PADDING-LEFT: 0pt; PADDING-RIGHT: 0pt; DISPLAY: inline; COLOR: black; PADDING-TOP: 0pt">bstrVal</SPAN>ue); <BR>AfxMessageBox(buf); <BR>delete(buf); 
<LI><FONT color=#6699ff>CComBSTR变量</FONT><BR>CComBSTR bstrVar("test"); <BR>char *buf = _com_util::ConvertBSTRToString(bstrVar.m_str); <BR>AfxMessageBox(buf); <BR>delete(buf); 
<LI><FONT color=#6699ff>_bstr_t变量</FONT><BR>_bstr_t类型是对BSTR的封装，因为已经重载了=操作符，所以很容易使用<BR>_bstr_t bstrVar("test"); <BR>const char *buf = bstrVar;///不要修改buf中的内容 <BR>AfxMessageBox(buf); 
<LI><FONT color=#6699ff>通用方法(针对非COM数据类型)</FONT><BR>用sprintf完成转换<BR><PRE>char  buffer[200];char  c = '1';int   i = 35;long  j = 1000;float f = 1.7320534f;sprintf( buffer, "%c",c);sprintf( buffer, "%d",i);sprintf( buffer, "%d",j);sprintf( buffer, "%f",f);</PRE></LI></UL>
<P><STRONG><FONT color=#6699ff>二、字符串转换为其它数据类型</FONT></STRONG><BR>strcpy(temp,"123");</P>
<UL>
<LI><FONT color=#6699ff>短整型(int)</FONT><BR>i = atoi(temp); 
<LI><FONT color=#6699ff>长整型(long)</FONT><BR>l = atol(temp); 
<LI><FONT color=#6699ff>浮点(double)</FONT><BR>d = atof(temp); 
<LI><FONT color=#6699ff>CString变量</FONT><BR>CString name = temp; 
<LI><FONT color=#6699ff>BSTR变量</FONT> <BR>BSTR <SPAN style="PADDING-BOTTOM: 0pt; BACKGROUND-COLOR: yellow; PADDING-LEFT: 0pt; PADDING-RIGHT: 0pt; DISPLAY: inline; COLOR: black; PADDING-TOP: 0pt">bstrVal</SPAN>ue = ::SysAllocString(L"程序员"); <BR>...///完成对<SPAN style="PADDING-BOTTOM: 0pt; BACKGROUND-COLOR: yellow; PADDING-LEFT: 0pt; PADDING-RIGHT: 0pt; DISPLAY: inline; COLOR: black; PADDING-TOP: 0pt">bstrVal</SPAN>ue的使用<BR>SysFreeString(<SPAN style="PADDING-BOTTOM: 0pt; BACKGROUND-COLOR: yellow; PADDING-LEFT: 0pt; PADDING-RIGHT: 0pt; DISPLAY: inline; COLOR: black; PADDING-TOP: 0pt">bstrVal</SPAN>ue); 
<LI><FONT color=#6699ff>CComBSTR变量</FONT><BR>CComBSTR类型变量可以直接赋值<BR>CComBSTR bstrVar1("test");<BR>CComBSTR bstrVar2(temp); 
<LI><FONT color=#6699ff>_bstr_t变量</FONT><BR>_bstr_t类型的变量可以直接赋值<BR>_bstr_t bstrVar1("test"); <BR>_bstr_t bstrVar2(temp); </LI></UL>
<P><STRONG><FONT color=#6699ff>三、其它数据类型转换到CString</FONT></STRONG><BR>使用CString的成员函数Format来转换,例如:</P>
<UL>
<LI>整数(int)<BR>str.Format("%d",i); 
<LI>浮点数(float)<BR>str.Format("%f",i); 
<LI>字符串指针(char *)等已经被CString构造函数支持的数据类型可以直接赋值<BR>str = username; 
<LI>对于Format所不支持的数据类型，可以通过上面所说的关于其它数据类型转化到char *的方法先转到char *，然后赋值给CString变量。 </LI></UL>
<P><STRONG><FONT color=#6699ff>四、BSTR、_bstr_t与CComBSTR</FONT></STRONG></P>
<UL>
<LI>CComBSTR 是ATL对BSTR的封装，_bstr_t是C++对BSTR的封装,BSTR是32位指针,但并不直接指向字串的缓冲区。<BR>char *转换到BSTR可以这样: <BR>BSTR b=_com_util::ConvertStringToBSTR("数据");///使用前需要加上comutil.h和comsupp.lib<BR>SysFreeString(<SPAN style="PADDING-BOTTOM: 0pt; BACKGROUND-COLOR: yellow; PADDING-LEFT: 0pt; PADDING-RIGHT: 0pt; DISPLAY: inline; COLOR: black; PADDING-TOP: 0pt">bstrVal</SPAN>ue); <BR>反之可以使用<BR>char *p=_com_util::ConvertBSTRToString(b);<BR>delete p;<BR>具体可以参考一，二段落里的具体说明。<BR><BR>CComBSTR与_bstr_t对大量的操作符进行了重载，可以直接进行=,!=,==等操作，所以使用非常方便。<BR>特别是_bstr_t,建议大家使用它。 </LI></UL>
<P><STRONG><FONT color=#6699ff>五、VARIANT 、_variant_t 与 COleVariant</FONT></STRONG></P>
<UL>
<LI>VARIANT的结构可以参考头文件VC98\Include\OAIDL.H中关于结构体tagVARIANT的定义。<BR>对于VARIANT变量的赋值：首先给vt成员赋值，指明数据类型，再对联合结构中相同数据类型的变量赋值，举个例子：<BR>VARIANT va;<BR>int a=2001;<BR>va.vt=VT_I4;///指明整型数据<BR>va.lVal=a; ///赋值<BR><BR>对于不马上赋值的VARIANT，最好先用Void VariantInit(VARIANTARG FAR* pvarg);进行初始化,其本质是将vt设置为VT_EMPTY,下表我们列举vt与常用数据的对应关系:<BR><BR>
<TABLE class=FCK__ShowTableBorders border=0 cellSpacing=1 cellPadding=0 width=792 bgColor=#333333>
<TBODY>
<TR bgColor=#ffffff>
<TD width=442>Byte bVal;</TD>
<TD width=338>// VT_UI1.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>Short iVal;</TD>
<TD width=338>// VT_I2.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>long lVal;</TD>
<TD width=338>// VT_I4.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>float fltVal;</TD>
<TD width=338>// VT_R4.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>double dblVal;</TD>
<TD width=338>// VT_R8.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>VARIANT_BOOL boolVal;</TD>
<TD width=338>// VT_BOOL.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>SCODE scode;</TD>
<TD width=338>// VT_ERROR.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>CY cyVal;</TD>
<TD width=338>// VT_CY.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>DATE date;</TD>
<TD width=338>// VT_DATE.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>BSTR <SPAN style="PADDING-BOTTOM: 0pt; BACKGROUND-COLOR: yellow; PADDING-LEFT: 0pt; PADDING-RIGHT: 0pt; DISPLAY: inline; COLOR: black; PADDING-TOP: 0pt">bstrVal</SPAN>;</TD>
<TD width=338>// VT_BSTR.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>DECIMAL FAR* pdecVal</TD>
<TD width=338>// VT_BYREF|VT_DECIMAL.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>IUnknown FAR* punkVal;</TD>
<TD width=338>// VT_UNKNOWN.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>IDispatch FAR* pdispVal;</TD>
<TD width=338>// VT_DISPATCH.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>SAFEARRAY FAR* parray;</TD>
<TD width=338>// VT_ARRAY|*.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>Byte FAR* pbVal;</TD>
<TD width=338>// VT_BYREF|VT_UI1.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>short FAR* piVal;</TD>
<TD width=338>// VT_BYREF|VT_I2.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>long FAR* plVal;</TD>
<TD width=338>// VT_BYREF|VT_I4.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>float FAR* pfltVal;</TD>
<TD width=338>// VT_BYREF|VT_R4.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>double FAR* pdblVal;</TD>
<TD width=338>// VT_BYREF|VT_R8.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>VARIANT_BOOL FAR* pboolVal;</TD>
<TD width=338>// VT_BYREF|VT_BOOL.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>SCODE FAR* pscode;</TD>
<TD width=338>// VT_BYREF|VT_ERROR.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>CY FAR* pcyVal;</TD>
<TD width=338>// VT_BYREF|VT_CY.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>DATE FAR* pdate;</TD>
<TD width=338>// VT_BYREF|VT_DATE.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>BSTR FAR* p<SPAN style="PADDING-BOTTOM: 0pt; BACKGROUND-COLOR: yellow; PADDING-LEFT: 0pt; PADDING-RIGHT: 0pt; DISPLAY: inline; COLOR: black; PADDING-TOP: 0pt">bstrVal</SPAN>;</TD>
<TD width=338>// VT_BYREF|VT_BSTR.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>IUnknown FAR* FAR* ppunkVal;</TD>
<TD width=338>// VT_BYREF|VT_UNKNOWN.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>IDispatch FAR* FAR* ppdispVal;</TD>
<TD width=338>// VT_BYREF|VT_DISPATCH.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>SAFEARRAY FAR* FAR* pparray;</TD>
<TD width=338>// VT_ARRAY|*.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>VARIANT FAR* pvarVal;</TD>
<TD width=338>// VT_BYREF|VT_VARIANT.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>void FAR* byref;</TD>
<TD width=338>// Generic ByRef.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>char cVal;</TD>
<TD width=338>// VT_I1.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>unsigned short uiVal;</TD>
<TD width=338>// VT_UI2.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>unsigned long ulVal;</TD>
<TD width=338>// VT_UI4.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>int intVal;</TD>
<TD width=338>// VT_INT.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>unsigned int uintVal;</TD>
<TD width=338>// VT_UINT.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>char FAR * pcVal;</TD>
<TD width=338>// VT_BYREF|VT_I1.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>unsigned short FAR * puiVal;</TD>
<TD width=338>// VT_BYREF|VT_UI2.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>unsigned long FAR * pulVal;</TD>
<TD width=338>// VT_BYREF|VT_UI4.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>int FAR * pintVal;</TD>
<TD width=338>// VT_BYREF|VT_INT.</TD></TR>
<TR bgColor=#ffffff>
<TD width=442>unsigned int FAR * puintVal;</TD>
<TD width=338>//VT_BYREF|VT_UINT.</TD></TR></TBODY></TABLE>
<LI>_variant_t是VARIANT的封装类，其赋值可以使用强制类型转换，其构造函数会自动处理这些数据类型。<BR>使用时需加上#include &lt;comdef.h&gt;<BR>例如：<BR>long l=222;<BR>ing i=100;<BR>_variant_t lVal(l);<BR>lVal = (long)i; 
<LI>COleVariant的使用与_variant_t的方法基本一样，请参考如下例子：<BR>COleVariant v3 = "字符串", v4 = (long)1999;<BR>CString str =(BSTR)v3.p<SPAN style="PADDING-BOTTOM: 0pt; BACKGROUND-COLOR: yellow; PADDING-LEFT: 0pt; PADDING-RIGHT: 0pt; DISPLAY: inline; COLOR: black; PADDING-TOP: 0pt">bstrVal</SPAN>;<BR>long i = v4.lVal; </LI></UL>
<P><FONT color=#6699ff><STRONG>六、其它一些COM数据类型</STRONG></FONT></P>
<UL>
<LI>根据ProgID得到CLSID<BR>HRESULT CLSIDFromProgID( LPCOLESTR lpszProgID,LPCLSID pclsid);<BR>CLSID clsid;<BR>CLSIDFromProgID( L"MAPI.Folder",&amp;clsid); 
<LI>根据CLSID得到ProgID<BR>WINOLEAPI ProgIDFromCLSID( REFCLSID clsid,LPOLESTR * lplpszProgID); <BR>例如我们已经定义了 CLSID_IApplication,下面的代码得到ProgID<BR>LPOLESTR pProgID = 0;<BR>ProgIDFromCLSID( CLSID_IApplication,&amp;pProgID);<BR>...///可以使用pProgID <BR>CoTaskMemFree(pProgID);//不要忘记释放 </LI></UL>
<P><FONT color=#6699ff><STRONG>七、ANSI与Unicode<BR></STRONG></FONT>Unicode称为宽字符型字串,COM里使用的都是Unicode字符串。</P>
<UL>
<LI>将ANSI转换到Unicode<BR>(1)通过L这个宏来实现，例如: CLSIDFromProgID( L"MAPI.Folder",&amp;clsid);<BR>(2)通过MultiByteToWideChar函数实现转换,例如:<BR>char *szProgID = "MAPI.Folder";<BR>WCHAR szWideProgID[128];<BR>CLSID clsid;<BR>long lLen = MultiByteToWideChar(CP_ACP,0,szProgID,strlen(szProgID),szWideProgID,sizeof(szWideProgID));<BR>szWideProgID[lLen] = '\0'; <BR>(3)通过A2W宏来实现,例如: <BR>USES_CONVERSION; <BR>CLSIDFromProgID( A2W(szProgID),&amp;clsid); 
<LI>将Unicode转换到ANSI<BR>(1)使用WideCharToMultiByte,例如:<BR>// 假设已经有了一个Unicode 串 wszSomeString... <BR>char szANSIString [MAX_PATH]; <BR>WideCharToMultiByte ( CP_ACP, WC_COMPOSITECHECK, wszSomeString, -1, szANSIString, sizeof(szANSIString), NULL, NULL ); <BR>(2)使用W2A宏来实现,例如:<BR>USES_CONVERSION;<BR>pTemp=W2A(wszSomeString); </LI></UL>
<P><FONT color=#6699ff><STRONG>八、其它</STRONG></FONT></P>
<UL>
<LI>对消息的处理中我们经常需要将WPARAM或LPARAM等32位数据（DWORD)分解成两个16位数据（WORD),例如：<BR>LPARAM lParam;<BR>WORD loValue = LOWORD(lParam);///取低16位<BR>WORD hiValue = HIWORD(lParam);///取高16位 
<LI>对于16位的数据(WORD)我们可以用同样的方法分解成高低两个8位数据(BYTE),例如:<BR>WORD wValue;<BR>BYTE loValue = LOBYTE(wValue);///取低8位<BR>BYTE hiValue = HIBYTE(wValue);///取高8位 
<LI>两个16位数据（WORD）合成32位数据(DWORD,LRESULT,LPARAM,或WPARAM)<BR>LONG MAKELONG( WORD wLow, WORD wHigh );<BR>WPARAM MAKEWPARAM( WORD wLow, WORD wHigh ); <BR>LPARAM MAKELPARAM( WORD wLow, WORD wHigh );<BR>LRESULT MAKELRESULT( WORD wLow, WORD wHigh ); 
<LI>两个8位的数据(BYTE)合成16位的数据(WORD)<BR>WORD MAKEWORD( BYTE bLow, BYTE bHigh ); 
<LI>从R(red),G(green),B(blue)三色得到COLORREF类型的颜色值<BR>COLORREF RGB( BYTE byRed,BYTE byGreen,BYTE byBlue );<BR>例如COLORREF bkcolor = RGB(0x22,0x98,0x34); 
<LI>从COLORREF类型的颜色值得到RGB三个颜色值<BR>BYTE Red = GetRValue(bkcolor); ///得到红颜色<BR>BYTE Green = GetGValue(bkcolor); ///得到绿颜色<BR>BYTE Blue = GetBValue(bkcolor); ///得到兰颜色 </LI></UL>
<P><FONT color=#6699ff><STRONG>九、注意事项</STRONG></FONT><BR>假如需要使用到ConvertBSTRToString此类函数,需要加上头文件comutil.h,并在setting中加入comsupp.lib或者直接加上#pragma comment( lib, "comsupp.lib" )</P></DIV></DIV>]]></description>
</item><item>
<title><![CDATA[好久没有来了]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=sccwqiang&amp;id=44488</link>
<author>sccwqiang</author>
<pubDate>2009/4/7 14:49:16</pubDate>
<description><![CDATA[<P>&#160; 好久没有写博客，今天有空随便写一下，下面是我自己搞的一个VC下联接ORACLE一段代码。第一次写的，对以后肯定是有些帮助的，所以拿上来，以后可以看一看。</P>
<P>DWORD WINAPI ProcessOracle(LPVOID lpParameter)<BR>{<BR>&#160;while(TRUE)<BR>&#160;{&#160;<BR>&#160;&#160;bThreadStart = TRUE;<BR>&#160;&#160;CoInitialize(NULL);<BR>&#160;&#160;_ConnectionPtr pConn(__uuidof(Connection));<BR>&#160;&#160;_RecordsetPtr pRecord(__uuidof(Recordset));<BR>&#160;&#160;<BR>&#160;&#160;pConn->ConnectionString = "Provider=OraOLEDB.Oracle.1;Password=appuser;Persist Security Info=True;User ID=appuser;Data Source=TESTDB";<BR>&#160;&#160;pConn->Open("","","",adConnectUnspecified);//<BR>&#160;&#160;<BR>&#160;&#160;pRecord = pConn->Execute("select * from yyr_mbinside_feectrl",NULL,adCmdText);<BR>&#160;&#160;while (!pRecord->rsEOF)<BR>&#160;&#160;{<BR>&#160;&#160;&#160;ITEM_KEY *key = new ITEM_KEY();<BR>&#160;&#160;&#160;ITEM_KEYVALUE keyValue ;<BR>&#160;&#160;&#160;//先KEY值<BR>&#160;&#160;&#160;key->m_Coid = (char*)(_bstr_t)pRecord->Fields->GetItem((_variant_t)"COID") ->Value;<BR>&#160;&#160;&#160;key->m_Operator = (char*)(_bstr_t)pRecord->Fields->GetItem((_variant_t)"OPERATOR") ->Value;<BR>&#160;&#160;&#160;key->m_Province = (char*)(_bstr_t)pRecord->Fields->GetItem((_variant_t)"PROVINCE") ->Value;<BR>&#160;&#160;&#160;//再得到KEYVALUE值<BR>&#160;&#160;&#160;keyValue.m_Daylimit = (char*)(_bstr_t)pRecord->Fields->GetItem((_variant_t)"daylimit") ->Value;<BR>&#160;&#160;&#160;keyValue.m_Monthlimit = (char*)(_bstr_t)pRecord->Fields->GetItem((_variant_t)"monthlimit") ->Value;<BR>&#160;&#160;&#160;//入栈<BR>&#160;&#160;&#160;item.insert(PROCESS_PER_ITEM::value_type(*key,keyValue));<BR>&#160;&#160;&#160;//把申请的内存块进入LIST中，以后好KISS掉<BR>&#160;&#160;&#160;listItem.push_back(key);<BR>&#160;&#160;&#160;pRecord->MoveNext();<BR>&#160;&#160;&#160;//DELETE_POINT(key);<BR>&#160;&#160;}<BR>&#160;&#160;/*char *pc = new char[40];&#160;memset(pc,0,40);sprintf(pc,"%d",item.size());::MessageBox(NULL,pc,"SIZE OF ITEM",MB_OK);&#160;break;*/<BR>&#160;&#160;bThreadStart = FALSE;<BR>&#160;&#160;::Sleep(1000 * 60 * 10);<BR>&#160;&#160;//先放掉已申请的内存<itemlist key的值><BR>&#160;&#160;LIST_ITEM::iterator it;<BR>&#160;&#160;for(it=listItem.begin();it!=listItem.end();++it)<BR>&#160;&#160;{<BR>&#160;&#160;&#160;DELETE_POINT(*it);<BR>&#160;&#160;}<BR>&#160;&#160;//全部关闭掉，并且清空MAP列表<BR>&#160;&#160;pRecord->Close();<BR>&#160;&#160;pConn->Close();<BR>&#160;&#160;pRecord.Release();<BR>&#160;&#160;pConn.Release();<BR>&#160;&#160;item.clear();<BR>&#160;&#160;CoUninitialize();<BR>&#160;}<BR>&#160;<BR>&#160;return 1;<BR>}</P>]]></description>
</item><item>
<title><![CDATA[指针初始化引出的问题]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=sccwqiang&amp;id=40939</link>
<author>sccwqiang</author>
<pubDate>2008/10/31 12:24:42</pubDate>
<description><![CDATA[
<P>对指针初始化时，引出的应该注意的问题小结：<BR>(1)先看例子：<BR>#include &lt;iostream.h&gt;</P>
<P>void main()<BR>{<BR>char *p,*p1="hello first!";<BR>while((*(p++) = *(p1++)) != 0);</P>
<P>cout&lt;&lt;p&lt;&lt;endl;<BR>}错处：p定义时没有初始化，p是指向不定，是一个野指针。<BR>p++可能引用得空间为非法的。<BR>编译时不会出错，但运行时会造成程序崩溃。</P>
<P>(2)把上面的p初始化为NULL<BR>#include &lt;iostream.h&gt;</P>
<P>void main()<BR>{<BR>char *p=NULL,*p1="hello first!";<BR>while((*(p++) = *(p1++)) != 0);</P>
<P>cout&lt;&lt;p&lt;&lt;endl;<BR>}//也错，NULL表示没有任何指向。p++没有任何意义，运行时会造成程序崩溃。这里就应该想到不能对NULL的指针进行直接操作。</P>
<P><BR>(3)现在为p初始化为" ":<BR>void main()<BR>{<BR>char *p=" ",*p1="hello first!";</P>
<P>while((*(p++) = *(p1++)) != 0);</P>
<P>cout&lt;&lt;p&lt;&lt;endl;<BR>}//错：p指向的是一个const常量的内容，可以通过*(p++)形式引用该值，但是不能改变它指向const的内容。<BR>(4)#include &lt;iostream.h&gt;<BR>#include &lt;string.h&gt;<BR>void main()<BR>{<BR>&nbsp;char c[]="";<BR>&nbsp;char *p=c,*p1="hello first!";<BR>&nbsp;char *p_start=p;<BR>&nbsp;while((*(p++) = *(p1++)) != 0);<BR>&nbsp;<BR>&nbsp;cout&lt;&lt;c&lt;&lt;endl;<BR>}//此时数组是一系列的变量了，也就是p一有指向，二不是指向常量的而是指向变量的。所以按理应该行的。问题出在c太小，造成了数组越界，所以错掉！把c的大小改来不比"hello first!"小就行了。<BR>(5)对于的就想到用new来初始化了：<BR>#include &lt;iostream.h&gt;<BR>#include &lt;string.h&gt;<BR>void main()<BR>{<BR>&nbsp;char *p,*p1="hello first!";<BR>&nbsp;p=new char;<BR>&nbsp;char *p_start=p;<BR>&nbsp;while((*(p++) = *(p1++)) != 0);<BR>&nbsp;<BR>&nbsp;cout&lt;&lt;p_start&lt;&lt;endl;<BR>}//现在就可以了，哈，不过，我认为在new时最好还是把它的大小给指出来，<BR>如new char[strlen(p1)+1];如果不指定大小，我想p++会指向一些已用得地址,而这些地址又不能随便改，就会造成诸如野指针样程序崩溃了。</P>
<P>小结：对于前面的问题，不防这样来写：<BR>#include &lt;iostream.h&gt;<BR>#include &lt;string.h&gt;<BR>void main()<BR>{<BR>&nbsp;char *p=NULL,*p1="hello first!";<BR>&nbsp;p=new char[strlen(p1)+1];<BR>&nbsp;//p=new char;//觉得最好别这样子，new char只相当于得到一个char对<BR>&nbsp;char *p_start=p;//象,分配一个字符的空间。<BR>&nbsp;while((*(p++) = *(p1++)) != 0);<BR>&nbsp;<BR>&nbsp;cout&lt;&lt;p_start&lt;&lt;endl;<BR>}<BR></P>]]></description>
</item><item>
<title><![CDATA[+,-*,/重载返回值不能用引用？]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=sccwqiang&amp;id=40818</link>
<author>sccwqiang</author>
<pubDate>2008/10/26 11:23:16</pubDate>
<description><![CDATA[
<P>&nbsp; 在网上看见有网友说重载+,-,*,/时返回值不能为对象的引用，带着深深的疑问自己动手来看了一下，可以呀！不管是成员还是友员重载两者都行，不知道他们是怎么想的，反正我在vc6.0中小试了一下能够通过！以下是用一复数加法运算，代码如下：</P>
<P>#include &lt;iostream.h&gt;</P>
<P>class complex<BR>{<BR>public:<BR>&nbsp;complex(){real=0;image=0;}<BR>&nbsp;complex(double r,double i){real=r;image=i;}<BR>&nbsp;//friend complex &amp;operator+(complex c1,complex c2);<BR>&nbsp;void display();<BR>&nbsp;complex &amp;operator+(complex c1);<BR>private:<BR>&nbsp;double real,image;<BR>};<BR>complex co;//全局对象<BR>/*complex &amp;operator+(complex c1,complex c2)//友员返回的引用<BR>{<BR>&nbsp;<BR>&nbsp;co.image=c1.image+c2.image;<BR>&nbsp;co.real=c1.real+c2.real;<BR>&nbsp;return co;<BR>}*/<BR>complex &amp;complex::operator +(complex c1)//重载为成员函数引用<BR>{<BR>&nbsp;co.real=real+c1.real;<BR>&nbsp;co.image=image+c1.image;<BR>&nbsp;return co;<BR>}</P>
<P>void complex::display()<BR>{<BR>&nbsp;cout&lt;&lt;real;<BR>&nbsp;if(image&gt;=0)cout&lt;&lt;"+"&lt;&lt;image&lt;&lt;"i"&lt;&lt;endl;<BR>&nbsp;else&nbsp; <BR>&nbsp;&nbsp;cout&lt;&lt;image&lt;&lt;"i"&lt;&lt;endl;<BR>}</P>
<P>int main()<BR>{<BR>&nbsp;complex c1(3,4),c2(5,-10),c;<BR>&nbsp;c=c1+c2;<BR>&nbsp;c.display();<BR>&nbsp;&nbsp;&nbsp; return 0;<BR>}</P>
<P>结果：8-6i<BR>Press any key to continue</P>
<P>从上可知返回引用是可以的可以的。但是如果用c1+c2=c的放系统不会报错！这个人认为就该是重载=的问题，因为就算不返回引用也上式系统也不会报错的。还有可能VC是不是很支持C++标准的。也许在其它环境下，不能返回对像引用吧！</P>]]></description>
</item><item>
<title><![CDATA[C/C++内存区分配（转）]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=sccwqiang&amp;id=40804</link>
<author>sccwqiang</author>
<pubDate>2008/10/25 10:03:32</pubDate>
<description><![CDATA[<A></A>
<TABLE style="TABLE-LAYOUT: fixed">
<TBODY>
<TR>
<TD>
<DIV class=cnt id=blog_text>
<DIV class=tit></DIV>
<TABLE style="TABLE-LAYOUT: fixed">
<TBODY>
<TR>
<TD>
<DIV class=cnt>一.在c中分为这几个存储区<BR>1.栈 - 有编译器自动分配释放<BR>2.堆 - 一般由程序员分配释放，若程序员不释放，程序结束时可能由OS回收<BR>3.全局区（静态区），全局变量和静态变量的存储是放在一块的，初始化的全局变量和静态变量在一块区域，未初始化的全局变量和未初始化的静态变量在相邻的&gt;另一块区域。- 程序结束释放<BR>4.另外还有一个专门放常量的地方。 - 程序结束释放<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>在函数体中定义的变量通常是在栈上，用malloc, calloc, realloc等分配内存的函数分配得到的就是在堆上。在所有函数体外定义的是全局量，加了static修饰符后不管在哪里都存放在全局区（静态区）,在所有函数体外定义的static变量表示在该文件中有效，不能extern到别的文件用，在函数体内定义的static表示只在该函数体内有效。另外，函数中的"adgfdf"这样的字符串存放在常量区。比如：<BR>代码：<BR>int a = 0; //全局初始化区<BR>char *p1; //全局未初始化区<BR>main()<BR>{<BR>int b; //栈<BR>char s[] = "abc"; //栈<BR>char *p2; //栈<BR>char *p3 = "123456"; //123456{post.content}在常量区，p3在栈上。<BR>static int c = 0； //全局（静态）初始化区<BR>p1 = (char *)malloc(10);<BR>p2 = (char *)malloc(20);<BR>//分配得来得10和20字节的区域就在堆区。<BR>strcpy(p1, "123456");<BR>//123456{post.content}放在常量区，编译器可能会将它与p3所指向的"123456"优化成一块。<BR>}<BR>二.在C++中，内存分成5个区，他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。<BR>1.栈，就是那些由编译器在需要的时候分配，在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。<BR>2.堆，就是那些由new分配的内存块，他们的释放编译器不去管，由我们的应用程序去控制，一般一个new就要对应一个delete。如果程序员没有释放掉，那么在程&gt;序结束后，操作系统会自动回收。<BR>3.自由存储区，就是那些由malloc等分配的内存块，他和堆是十分相似的，不过它是用free来结束自己的生命的。<BR>4.全局/静态存储区，全局变量和静态变量被分配到同一块内存中，在以前的C语言中，全局变量又分为初始化的和未初始化的，在C++里面没有这个区分了，他们共同占用同一块内存区。<BR>5.常量存储区，这是一块比较特殊的存储区，他们里面存放的是常量，不允许修改（当然，你要通过非正当手段也可以修改）<BR>现在来谈谈堆与栈的关系与区别:<BR>具体地说，现代计算机(串行执行机制)，都直接在代码底层支持栈的数据结构。这体现在，有专门的寄存器指向栈所在的地址，有专门的机器指令完成数据入栈出&gt;栈的操作。这种机制的特点是效率高，支持的数据有限，一般是整数，指针，浮点数等系统直接支持的数据类型，并不直接支持其他的数据结构。因为栈的这种特&gt;点，对栈的使用在程序中是非常频繁的。对子程序的调用就是直接利用栈完成的。机器的call指令里隐含了把返回地址推入栈，然后跳转至子程序地址的操作，而&gt;子程序中的ret指令则隐含从堆栈中弹出返回地址并跳转之的操作。C/C++中的自动变量是直接利用栈的例子，这也就是为什么当函数返回时，该函数的自动变量自&gt;动失效的原因。 <BR><BR>和栈不同，堆的数据结构并不是由系统(无论是机器系统还是操作系统)支持的，而是由函数库提供的。基本的malloc/realloc/free 函数维护了一套内部的堆数据&gt;结构。当程序使用这些函数去获得新的内存空间时，这套函数首先试图从内部堆中寻找可用的内存空间，如果没有可以使用的内存空间，则试图利用系统调用来动&gt;态增加程序数据段的内存大小，新分配得到的空间首先被组织进内部堆中去，然后再以适当的形式返回给调用者。当程序释放分配的内存空间时，这片内存空间被&gt;返回内部堆结构中，可能会被适当的处理(比如和其他空闲空间合并成更大的空闲空间)，以更适合下一次内存分配申请。这套复杂的分配机制实际上相当于一个内&gt;存分配的缓冲池(Cache)，使用这套机制有如下若干原因：<BR>1. 系统调用可能不支持任意大小的内存分配。有些系统的系统调用只支持固定大小及其倍数的内存请求(按页分配)；这样的话对于大量的小内存分类来说会造成浪费。<BR>2. 系统调用申请内存可能是代价昂贵的。系统调用可能涉及用户态和核心态的转换。<BR>3. 没有管理的内存分配在大量复杂内存的分配释放操作下很容易造成内存碎片。<BR><BR>堆和栈的对比:<BR>从以上知识可知，栈是系统提供的功能，特点是快速高效，缺点是有限制，数据不灵活；而栈是函数库提供的功能，特点是灵活方便，数据适应面广泛，但是效率 &gt;有一定降低。栈是系统数据结构，对于进程/线程是唯一的；堆是函数库内部数据结构，不一定唯一。不同堆分配的内存无法互相操作。栈空间分静态分配和动态分配两种。静态分配是编译器完成的，比如自动变量(auto)的分配。动态分配由alloca函数完成。栈的动态分配无需释放(是自动的)，也就没有释放函数。为可移植&gt;的程序起见，栈的动态分配操作是不被鼓励的！堆空间的分配总是动态的，虽然程序结束时所有的数据空间都会被释放回系统，但是精确的申请内存/ 释放内存匹&gt;配是良好程序的基本要素。<BR><BR>&nbsp;&nbsp;&nbsp; 1.碎片问题：对于堆来讲，频繁的new/delete势必会造成内存空间的不连续，从而造成大量的碎片，使程序效率降低。对于栈来讲，则不会存在这个问题，因为栈是先进后出的队列，他们是如此的一一对应，以至于永远都不可能有一个内存块从栈中间弹出，在他弹出之前，在他上面的后进的栈内容已经被弹出，详细的可以&gt;参考数据结构，这里我们就不再一一讨论了。<BR>&nbsp;&nbsp;&nbsp; 2.生长方向：对于堆来讲，生长方向是向上的，也就是向着内存地址增加的方向；对于栈来讲，它的生长方向是向下的，是向着内存地址减小的方向增长。<BR>&nbsp;&nbsp;&nbsp; 3.分配方式：堆都是动态分配的，没有静态分配的堆。栈有2种分配方式：静态分配和动态分配。静态分配是编译器完成的，比如局部变量的分配。动态分配由alloca函数进行分配，但是栈的动态分配和堆是不同的，他的动态分配是由编译器进行释放，无需我们手工实现。<BR>&nbsp;&nbsp;&nbsp; 4.分配效率：栈是机器系统提供的数据结构，计算机会在底层对栈提供支持：分配专门的寄存器存放栈的地址，压栈出栈都有专门的指令执行，这就决定了栈的效率比较高。堆则是C/C++函数库提供的，它的机制是很复杂的，例如为了分配一块内存，库函数会按照一定的算法（具体的算法可以参考数据结构/操作系统）在堆&gt;内存中搜索可用的足够大小的空间，如果没有足够大小的空间（可能是由于内存碎片太多），就有可能调用系统功能去增加程序数据段的内存空间，这样就有机会&gt;分到足够大小的内存，然后进行返回。显然，堆的效率比栈要低得多。<BR><BR>&nbsp;&nbsp;&nbsp; 明确区分堆与栈:<BR>&nbsp;&nbsp;&nbsp; 在bbs上，堆与栈的区分问题，似乎是一个永恒的话题，由此可见，初学者对此往往是混淆不清的，所以我决定拿他第一个开刀。<BR>&nbsp;&nbsp;&nbsp; 首先，我们举一个例子：<BR>&nbsp;&nbsp;&nbsp; void f() { int* p=new int[5]; }<BR>&nbsp;&nbsp;&nbsp; 这条短短的一句话就包含了堆与栈，看到new，我们首先就应该想到，我们分配了一块堆内存，那么指针p呢？他分配的是一块栈内存，所以这句话的意思就是：在栈内存中存放了一个指向一块堆内存的指针p。在程序会先确定在堆中分配内存的大小，然后调用operator new分配内存，然后返回这块内存的首地址，放入栈中，他在VC6下的汇编代码如下：<BR>&nbsp;&nbsp;&nbsp; 00401028&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 14h<BR>&nbsp;&nbsp;&nbsp; 0040102A&nbsp;&nbsp;&nbsp; call&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; operator new (00401060)<BR>&nbsp;&nbsp;&nbsp; 0040102F&nbsp;&nbsp;&nbsp; add&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; esp,4<BR>&nbsp;&nbsp;&nbsp; 00401032&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebp-8],eax<BR>&nbsp;&nbsp;&nbsp; 00401035&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; eax,dword ptr [ebp-8]<BR>&nbsp;&nbsp;&nbsp; 00401038&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dword ptr [ebp-4],eax<BR>&nbsp;&nbsp;&nbsp; 这里，我们为了简单并没有释放内存，那么该怎么去释放呢？是delete p么？澳，错了，应该是delete []p，这是为了告诉编译器：我删除的是一个数组，VC6&gt;就会根据相应的Cookie信息去进行释放内存的工作。<BR>&nbsp;&nbsp;&nbsp; 好了，我们回到我们的主题：堆和栈究竟有什么区别？<BR>&nbsp;&nbsp;&nbsp; 主要的区别由以下几点：<BR>&nbsp;&nbsp;&nbsp; 1、管理方式不同；<BR>&nbsp;&nbsp;&nbsp; 2、空间大小不同；<BR>&nbsp;&nbsp;&nbsp; 3、能否产生碎片不同；<BR>&nbsp;&nbsp;&nbsp; 4、生长方向不同；<BR>&nbsp;&nbsp;&nbsp; 5、分配方式不同；<BR>&nbsp;&nbsp;&nbsp; 6、分配效率不同；<BR>&nbsp;&nbsp;&nbsp; 管理方式：对于栈来讲，是由编译器自动管理，无需我们手工控制；对于堆来说，释放工作由程序员控制，容易产生memory leak。<BR>&nbsp;&nbsp;&nbsp; 空间大小：一般来讲在32位系统下，堆内存可以达到4G的空间，从这个角度来看堆内存几乎是没有什么限制的。但是对于栈来讲，一般都是有一定的空间大小的，例如，在VC6下面，默认的栈空间大小是1M（好像是，记不清楚了）。当然，我们可以修改：<BR>&nbsp;&nbsp;&nbsp; 打开工程，依次操作菜单如下：Project-&gt;Setting-&gt;Link，在Category 中选中Output，然后在Reserve中设定堆栈的最大值和commit。<BR>注意：reserve最小值为4Byte；commit是保留在虚拟内存的页文件里面，它设置的较大会使栈开辟较大的值，可能增加内存的开销和启动时间。<BR>&nbsp;&nbsp;&nbsp; 堆和栈相比，由于大量new/delete的使用，容易造成大量的内存碎片；由于没有专门的系统支持，效率很低；由于可能引发用户态和核心态的切换，内存的申请，代价变得更加昂贵。所以栈在程序中是应用最广泛的，就算是函数的调用也利用栈去完成，函数调用过程中的参数，返回地址，EBP和局部变量都采用栈的方式存放。所以，我们推荐大家尽量用栈，而不是用堆。<BR><BR>另外对存取效率的比较:<BR>代码:<BR>char s1[] = "aaaaaaaaaaaaaaa";<BR>char *s2 = "bbbbbbbbbbbbbbbbb";<BR>aaaaaaaaaaa是在运行时刻赋值的；<BR>而bbbbbbbbbbb是在编译时就确定的；<BR>但是，在以后的存取中，在栈上的数组比指针所指向的字符串(例如堆)快。<BR>比如：<BR>#include<BR>void main()<BR>{<BR>char a = 1;<BR>char c[] = "1234567890";<BR>char *p ="1234567890";<BR>a = c[1];<BR>a = p[1];<BR>return;<BR>}<BR>对应的汇编代码<BR>10: a = c[1];<BR>00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]<BR>0040106A 88 4D FC mov byte ptr [ebp-4],cl<BR>11: a = p[1];<BR>0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]<BR>00401070 8A 42 01 mov al,byte ptr [edx+1]<BR>00401073 88 45 FC mov byte ptr [ebp-4],al<BR>第一种在读取时直接就把字符串中的元素读到寄存器cl中，而第二种则要先把指针值读到edx中，在根据edx读取字符，显然慢了.<BR>&nbsp;&nbsp;&nbsp; 无论是堆还是栈，都要防止越界现象的发生（除非你是故意使其越界），因为越界的结果要么是程序崩溃，要么是摧毁程序的堆、栈结构，产生以想不到的结果,就算是在你的程序运行过程中，没有发生上面的问题，你还是要小心，说不定什么时候就崩掉,编写稳定安全的代码才是最重要的:)</DIV></TD></TR></TBODY></TABLE></DIV></TD></TR></TBODY></TABLE>]]></description>
</item><item>
<title><![CDATA[引用方式处理数组(原创)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=sccwqiang&amp;id=40790</link>
<author>sccwqiang</author>
<pubDate>2008/10/24 13:43:52</pubDate>
<description><![CDATA[
<P>&nbsp;我们知道c++中不能建立数引用的数组,因为数组名只是代表数组的首地址，而不是一个变量（显然它是常数嘛），所以不能建立引用的数组。当用数组作为参数进行传递时，一般相到指针方式的值传递。而有了C++的引用，它的优点使得有时候可能想这样做，就是形参用引用方式来进行处理。由于不能用引用形的数组（int &amp;arr[2][3])作为形参，所以象我等初学者认为这是不可能的。今天没事我就自己弄弄看，居然可以用引用。<U>思路大体如下：因可以建立指针的引用，所以想到中间代换，即先用一指针指向数组的首地址，然后再建立该指针的引用，这就相当于有了中间指针的别名，当改变别名的值时，就改变了中间指针变量中的值，而中间指针变量又是指向数组元数的，自然就改变了数组的值了。</U>例如：int a[2];先建立指向数组的指针int *p=a;然后就可建立指针的引用：int *&amp;pt=p;这是pt 其实就是指针p的别名了，也就是p和pt是同一个变量了，改变pt就等于改变p，而改变指针p就是改变了p指向的变量的值了。</P>
<P>下面是一个二行三列矩阵的加法运算，并输出结果,由于需要重载了&lt;&lt;和+,数据成员data是数据成员，一个二行三列的数组。多的就不说了，好多地方都标出来了，仔细看一下就知道了。</P>
<P>#include &lt;iostream.h&gt;</P>
<P><BR>/*====================声明矩阵类=========================*/<BR>class Rect<BR>{<BR>public:<BR>&nbsp;Rect();//声明无参构造函数<BR>&nbsp;Rect(int *&amp;p);&nbsp; //带一个参数的构造函数,用于二维数组的引用算法<BR>&nbsp;friend ostream &amp; operator&lt;&lt;(ostream &amp;,Rect &amp;); //友元重载&lt;&lt;运算符<BR>&nbsp;Rect operator+ (Rect &amp;other); //成员重载+运算符<BR>private:<BR>&nbsp;int data[2][3]; //二行三列矩阵</P>
<P>};</P>
<P>/*===============类体外相关定义=======================*/<BR>Rect::Rect()<BR>{<BR>for(int i=0;i&lt;2;i++)<BR>&nbsp;&nbsp;for(int j=0;j&lt;3;j++)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;data[i][j]=0;<BR>&nbsp;&nbsp;}<BR>}</P>
<P>Rect::Rect(int *&amp;p)<BR>{<BR>&nbsp;int *pt=data[0];<BR>&nbsp;int *&amp;p1=pt;<BR>&nbsp;for(int i=0;i&lt;6;i++)<BR>&nbsp;*(p1++)=*(p++);</P>
<P>}<BR>Rect Rect::operator+(Rect &amp;other) //定义成员重载+运算符<BR>{<BR>&nbsp;Rect ret;<BR>&nbsp;for(int i=0;i&lt;2;i++)<BR>&nbsp;&nbsp;for(int j=0;j&lt;3;j++)<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;ret.data[i][j]=data[i][j]+other.data[i][j];<BR>&nbsp;&nbsp;}<BR>&nbsp;&nbsp;return ret;<BR>}</P>
<P>ostream &amp;operator&lt;&lt;(ostream &amp; output,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Rect &amp;rect)//定义友元重载&lt;&lt;运算符<BR>{<BR>&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;2;i++)<BR>&nbsp;{<BR>&nbsp;&nbsp;for(int j=0;j&lt;3;j++)<BR>&nbsp;&nbsp;&nbsp;output&lt;&lt;rect.data[i][j]&lt;&lt;" ";<BR>&nbsp;&nbsp;output&lt;&lt;endl;<BR>&nbsp;}<BR>&nbsp;return output;<BR>}</P>
<P>/*==================主函数=====================*/<BR>void main()<BR>{<BR>&nbsp;int data1[2][3];//等待输入<BR>&nbsp;int data2[2][3]={{1,1,1},{2,2,2}};</P>
<P><BR>&nbsp;//int *pt=data1[0];<BR>&nbsp;for(int i=0,*pt=data1[0];i&lt;sizeof(data1)/sizeof(int);i++)<BR>&nbsp;{<BR>&nbsp;&nbsp;cin&gt;&gt;*(pt++);<BR>&nbsp;}</P>
<P>&nbsp;int *p2=data1[0];//先用一指针得到数组首地址<BR>&nbsp;Rect re1(p2);//此时调用指针引用<BR>&nbsp;p2=data2[0];<BR>&nbsp;Rect re2(p2);<BR>&nbsp;Rect re3;</P>
<P>&nbsp;re3=re2+re1;<BR>&nbsp;cout&lt;&lt;re3&lt;&lt;endl;<BR>}</P>
<P>输入:1 2 3 4 5 6</P>
<P>结果：1 2 3 4 5 6<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2 3 4<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6 7 8</P>
<P>Press any key to continue<BR>说明：二维数组：a[2][3];&nbsp; a=a[0];但是a+1 != a[0]+1;因a+1=a[1]=&amp;a[1][0]，而a[0]+1=&amp;a[0][1]</P>
<P>&nbsp;&nbsp;另外这是个人所得，不知是否孤陋寡闻，因不才看的c++书中没有介绍这种方法，如果有人看到相关的书，告知小弟一声！还有如果有误请指出，谢谢！<BR></P>]]></description>
</item><item>
<title><![CDATA[公交车上巨搞笑的一幕]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=sccwqiang&amp;id=40752</link>
<author>sccwqiang</author>
<pubDate>2008/10/21 23:46:22</pubDate>
<description><![CDATA[
<DIV class=articleTitle>
<DIV style="DISPLAY: inline"><SPAN class=time><FONT face=Arial color=#585858 size=1></FONT></SPAN></DIV></DIV>
<DIV class=articleTitle>
<DIV style="DISPLAY: inline"><SPAN class=time></SPAN>&nbsp;</DIV>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;&nbsp;<WBR><FONT color=#003366>今天在公交车上，由于拥挤一男一女发生了碰撞。&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　　　时髦女郎回头飞眼道：“你有病啊？”&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　　　男子觉得莫名其妙回道：“你有药吗？”&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　　　车上人窃笑！&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　　　女子觉得生气回道：“你有精神病啊？”&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　　　男子冷面对道：“你能治啊？”&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　　　全车人爆笑！&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　　　公交司机停车，趴在方向盘上大笑！&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　　这是珠江路上的朋友遇见的&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　　　公交车上超挤，有一女人站在门口，&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　　　从车后面挤过来一个ＧＧ要下车，&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　　　跟那女的说了一句“让一下，下车”，那个女滴木有动。&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　　　ＧＧ挤过去时就踩到她了。&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　　　结果那女人好厉害的，不停的骂“神经病啊你！神经病啊你！~~”，还超大声，搞得全车都看&nbsp;<WBR>&nbsp;<WBR> 呀。&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　　　ＧＧ一直木有说话，下车时忍不了了，回头对那女人说，“复读机呀你！”&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　　　全车人暴笑~！&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　　　后边有几个搞笑的小孩，不停的伴演刚才的一幕，&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　　　甲说“你神经病呀你！。。。。。乙说“你复读机呀你”。。。。。。&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　　　全车人暴笑~！&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　　　后来，有个小ＭＭ也要下车，挤过去怯怯滴说“偶~偶~偶想下去，偶不是神经病~！”&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　　　全车人再次暴笑~！&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　　　那个女人木有说话，可是从边上飘来一句话“你是不是没电了”&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR>&nbsp;<WBR><BR>　　　　全车人暴笑不止~！</FONT>&nbsp;<WBR>&nbsp;<WBR></DIV>]]></description>
</item><item>
<title><![CDATA[空姐在飞机上的事情]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=sccwqiang&amp;id=40718</link>
<author>sccwqiang</author>
<pubDate>2008/10/19 20:06:21</pubDate>
<description><![CDATA[<A><FONT color=#ff0000>　</FONT></A><FONT color=#ff0000> </FONT>
<DIV class=articleContent id=articleBody>
<DIV><SPAN class=size10><FONT size=3><FONT color=#ff0000>（一）飞机落地了，由于广播的乘务员老想着赶班车去东直门，于是广播成了“女士们，先生们，我们的飞机已经抵达首都北京东直门机场” 旅客疯了。。。<BR>（二）飞机抵达纽约，应该是肯尼迪机场，最后广播成了“我们已经抵达纽约肯德基机场”<BR>（三）回到北京，落地前乘务员要做好签封工作，刚签封完就有旅客要可乐，乘务员说“我们都封了”结果客人很不理解：“我就要个可乐，你们就疯（封）啦？！”<BR>（四）飞机机械故障延误了，过了一会又可以走了，旅客问为什么？乘务员说“没事儿，就换了一个敢开的机长。”<BR>（五）飞机落地了，还在滑行，旅客就都站起来拿行李，为了安全，要广播“女士们，先生们，我们的飞机还在滑行，请您坐好，并关闭头顶上方的行李架”结果一着急广播成了“女士们，先生们，我们的飞机滑得还行……”这时候，“叮——咚”内话响了，机长说“谁夸我呢？！”<BR>（六）乘务员广播“女士们，先生们，请您坐在跑道上，系好安全带，我们的飞机马上就要起飞了……”<BR>（七）话说，飞机起飞的时候，轰鸣声甚大，坐在头等仓的乘乘对另一乘乘说：“看，那个旅客的鼻毛露出来了”<BR>另一乘乘没有听见，大声问到：“什么？！”<BR>又大声重复一边还是没有听到，<BR>只见那个旅客走过来，说：“小姐，她说，我的鼻毛露出来了！！”<BR>（八）一天乘务长和一乘务员迎客, 上来一名外国黑人. 乘务长小声的对乘务员说:"你看那外国人可真黑啊~！（笑） " 第2秒钟外国黑人回头对哪个乘务长说:" 就你白!"<BR>（九）乘乘:我们有雪碧可乐矿泉水请问你需要喝什么?<BR>旅客:饮料!<BR>（十）乘乘:今天为您提供的热早餐有面条和点心,请问你需要哪一种?&gt;<BR>旅客沉思半晌：米饭!<BR>（十一）据闻俄罗斯最近又发生了一起劫机事件。<BR>在一架莫斯科飞往巴库的班机上，一名青年男子突然掏出一把玩具手枪大喊：“劫机!我要劫机!我要和机长对话!!”<BR>机长赶紧战战兢兢地过来了，小心冀冀地说道：“先生，您有什么意见尽管说，您的要求我们都尽量满足，请您先放下枪好吗?这样以免伤及无辜……”<BR>劫匪歇斯底里地吼道：“不!我现在只要求这架飞机立即飞往巴库!!”<BR>机长不禁诧异地问道：“哦，先生，您听我说，本次航班本来就是飞往巴库的，您可以把枪放下来了。顺便问一句：您的精神没有问题吧?”<BR>劫匪勃然大怒道：“你胡说八道什么?!我很好!我已经乘坐你们这个航班三次了，第一次将我劫到了阿富汗!第二次又将我劫到了伊拉克!”他抑制不住内心的激动说，“这不昨天才将我送回来，这一次无论如何，我都要先劫啦——我要回巴库!”<BR>（十二）前几天飞广州，上来大帮小红帽旅行团，收餐时见餐盘中餐盒统统被小红帽扣留，准备带回家做纪念，于是一乘务员耐心解释：这些都是必须回收的餐具，麻烦各位配合我们回收，有人上缴。但仍有个别假寐，拒不交出，再劝，又上缴几只，仍有个别顽固分子，坚持说已交给乘务员。于是另一乘务员忍无可忍，大声对另那名乘务员说：难道他们就不知道，下飞机时，门口会报警吗？此言一出，全数上缴！<BR>（十三）乘务员正在供餐，到一位旅客前问道：“先生，我们有鸡肉米饭和鱼肉米饭，请问您吃哪种？”<BR>旅客答道：“排骨！”<BR>乘务员又重复一遍，旅客依然答道：“排骨！”<BR>这时，乘务员问：“我们有鸡排骨和鱼排骨，您吃哪种？”<BR>（十四）呼唤铃响．空姐：您好，请问有什么可以帮您的吗？<BR>旅客：能要一杯水吗？<BR>空姐：当然可以，矿泉水吗？<BR>旅客：有果汁吗？<BR>空姐：有，橙汁和桃汁请问需要哪一种？<BR>旅客：有可乐吗？<BR>空姐：有，需要加冰吗？<BR>旅客：那给我一杯茶吧！<BR>（十五）一天飞737-700，一位后舱旅客上卫生间，站在卫生间门口一阵猛摇，乘务员好心提醒到：“先生，请往里推”。只见那位乘客用食指轻轻一戳，乘务员又说到“推”乘客再戳。乘务员：“用力推” 乘客一愣，猛吸一口气，对着卫生间一阵猛吹！乘务员们笑倒一片……急忙帮他开门道：“您太经典了，我是说用力推，不是用力吹！”<BR>（十六）厨房乘务员手拿两壶咖啡给客舱送去，一位旅客指着窗外问话：“小姐，这是什么湖啊？？？”乘务员答到“咖啡壶”旅客笑倒一片。<BR>（十七） cc：请问牛和鱼您喜欢哪种？<BR>PA：好的，我要牛和。<BR>cc：是牛，和鱼。<BR>PA：哦，那我要和鱼。<BR>（十八）乘客男第一次坐飞机，按动呼唤铃．乘务员：先生，请问有什么需要帮助吗？<BR>乘客男：默然<BR>乘务员：这是呼唤铃，如果有什么需要再按它，我们会帮助您！<BR>乘客男点点头．还没等乘务员回到坐位，只听呼唤铃又响了．只见乘客男站起来，嘴对着呼唤铃大声喊到：＂可乐－－加冰！！！＂<BR>（十九） 飞机上的尖叫声<BR>一架载着两百多名乘客的飞机平稳地飞行在高空。这时，广播里传来机长愉快的声音：“女士们，先生们，我是你们的机长，欢迎大家乘做我们的航班，我想告诉大家的是……啊！天哪！！”他发出这声KB的叫声后，广播里就没有声音了。<BR>所有的乘客都吓话坏了，连空姐也害怕的说不出话来。<BR>过了一会，广播终于又响了，还是机长：“女士们先生们，对不起，方才让大家受惊了。这里确实发生了一个小小的意外，但不是飞机，乘务员给我到咖啡的时候，不小心把咖啡撒在了我的衬衣上，不信你们来看都湿透了！”<BR>这时，机舱里响起一个乘客怒气冲天的抱怨声：“衬衫湿了算什么，你看看我的裤裆！！<BR>（二十） 高度位置<BR>导航员：“请报告你的高度、位置。”<BR>飞行员：“我大约1．8米高，现在正坐在驾驶员的座位上。”<BR>（二一）乘务长在机门口迎客,上来一位年轻小伙儿:欢迎您登机,请问您是什么座?cf问,"我是天蝎座,您呢?"<BR>我是巨蝎座,我是问您坐哪一个座位?&nbsp;<WBR>……&nbsp;<WBR></FONT></FONT></SPAN></DIV>
<DIV><SPAN class=size10><FONT color=#ff0000 size=3>（二十二）有个很讨厌的男旅客拿到配餐中的苹果问乘务员：“这个苹果怎麽吃啊？”<BR>乘务员回答：“啃皮”<BR>（二十三） 乘务员：“您好，请问喝点什么？”<BR>旅客不好意思道：“不喝，不喝。”<BR>于是乘务员小声的说道：“免费的哦。”<BR>旅客：“啊？免费的啊！我要一杯橙汁，一杯可乐，一杯咖啡，还要。。。”<BR>于是边说边从包里拿出一个瓶子说道：“再给我灌点豆浆在里面！我要把飞机票喝回来"<BR>（二十四）一个旅客捧着吃得干干净净的餐盘（连根菜叶都没剩下）说：小姐，你们的餐食太差了，简直就是狗食！！<BR>（二十五） 广州旅客喜欢问:小姐有没有奶茶?<BR>海南:亚子汁(椰子汁)<BR>小朋友;冰欺凌<BR>女孩；酸奶<BR>让我们无语的人；小姐，有燕窝吗？<BR>脑白金有吗？<BR>（二十六）乘务员：“鸡肉米饭和猪肉米饭请问要哪种？”<BR>旅客：“我们两个是猪，他是鸡！”<BR>（二十七） 旅客:"我要一杯可乐."<BR>乘务员不确定的问到:"你是可乐吗?"<BR>旅客:"不是!" 乘务员:"那你是?" 旅客:"我是人,我要可乐!"<BR>（二十八）某日，飞行中。<BR>一安全员看一旅客开手机，马上走过去严肃的说道：“不要在手机上打飞机！”<BR>（二十九） 旅客问：小姐，这是波音什么型号<BR>答：空客320<BR>旅客：我问你是什么型号<BR>答：320<BR>旅客：（比较大声）我问你是波音什么号<BR>答：是空中客车320<BR>旅客：你怎么这么犟呢！是波音几几几！！<BR>答：320<BR>旅客：你说波音320不就行了，乘务员连这都不知道！<BR>（三十）厕所里有马桶纸（垫马桶的纸），一个小红帽进去了，出来后他把马桶纸套在了脖子上而且很得意，兴奋的象团员们跑了过去说：快去厕所带个这，一会吃饭滴不到身上！一瞬间，满飞机的马桶纸~~~<BR>（三十一） 先生，我们有米饭和面条两种，请问你需要那一种？<BR>要要！<BR>要哪一种呢？<BR>有什么？<BR>米饭和面条两种，请问您需要哪一种呢</FONT></SPAN></DIV>
<DIV><SPAN class=size10><FONT color=#ff0000 size=3>沉思半天，问：米饭是什么做的，面条是什么做的？</FONT></SPAN></DIV>
<DIV><SPAN class=size10><FONT color=#ff0000 size=3>答：米饭是大米做的，面条是面粉做的！<BR>那，来米饭吧！倒！！！！<BR>(三十二) CC：先生您是喝橙汁还是喝苹果汁？<BR>答：你们这儿的橙汁有苹果味儿的吗？<BR>（三十三） 320飞机上，乘务员在收餐盘，大多数乘客都递上餐盘便于乘务员收取。一靠窗的乘客无动于衷，乘乘伸手够不着，便对他说：“麻烦您把餐盘递一下好吗？”那乘客傲慢地说道：“你是服务员，还是我是服务员？” 乘乘答道：“我是服务员，但我不是长臂猿！”<BR>（三十三）旅客问：“小姐，有指甲刀吗？”<BR>乘务员说：“您当我是小叮当啊？”</FONT></SPAN></DIV>
<P><FONT color=#ff0000>文章引用自：</FONT><A href="http://www.boyair.com/joke_view.asp?id=11653" target=_blank><FONT color=#ff0000>http://www.boyair.com/joke_view.asp?id=11653</FONT></A></P></DIV>]]></description>
</item><item>
<title><![CDATA[软件版本释义]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=sccwqiang&amp;id=40173</link>
<author>sccwqiang</author>
<pubDate>2008/9/21 10:25:25</pubDate>
<description><![CDATA[&nbsp; 
<TABLE cellSpacing=0 cellPadding=3 width=500 align=center border=0>
<TBODY>
<TR align=middle>
<TD class=FontMax><FONT size=2></FONT><B><FONT color=#ff0000 size=6>软件版本释义</FONT><BR></B><FONT size=2></FONT></TD></TR>
<TR>
<TD align=middle></TD></TR>
<TR>
<TD class=F11><FONT size=2>&nbsp;&nbsp;&nbsp;&nbsp; 或许，大家已经注意到了，网上下载的软件常常标有Beta版、Demo版等软件版本信息。这些版本标志实际上有其内在的含义。在此，把几种常见的软件版本向大家做一简单介绍。<BR>&nbsp;&nbsp;&nbsp;&nbsp;FullVersion: 式版。用户使用最多的版本，功能完备。<BR>&nbsp;&nbsp;&nbsp; Upgrade版: 增加低版本软件的功能，所具有的功能和正式版件相同。<BR>&nbsp;&nbsp;&nbsp; 以上两种版本的软件多以软盘或光盘形式发行，需要用户换腰包，拿钱购买。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;Beta版: 是软件公司在正式版发行前，推出的用户测试版，目的是对外宣传。该版本软件往往功能不全，有时还有时间限制，过期则需要重新安装，有的甚至拒绝再次安装。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;Demo版：Beta版相差无几。如果是游戏软件只能玩前几局，其他软件则有许多正式版所具有的功能无法使用。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;Release版：功能和正式版一样，是在正式版软件销售前推出的版本，目的是为了占领市场。但它有时间限制，在正式版推出时已不能再用。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;上述三种版本的软件大多可从因特网上下载，因是免费赠送，可省不少钱，为许多网虫所热衷。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;α版：内部测试版。与β版不同的是，α版只在软件公司内部试用测试。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;OEC版：OEM是Original Equipment Manufacture原始设备制造商的缩写。各大电脑厂商和软件公司之间往往建立一种合作关系，在各公司销售自己的产品时，可以附带他们的软件，所附带的他人的软件即是OEM版。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;注册版：较特殊的软件版本，软件可以从因特网上下载，但必须进行注册，从该软件的研制者那里取得注册码后，才能使用该软件的全部功能，否则软件的很多功能将不能使用。当然，注册码的取得通常不是免费的。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;至此，当“含情脉脉”的软件版本信息再向你“暗送秋波”时，相信你就不会被搞得满头雾水了吧。</FONT><BR></TD></TR></TBODY></TABLE>]]></description>
</item><item>
<title><![CDATA[数字万用表使用方法]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=sccwqiang&amp;id=40028</link>
<author>sccwqiang</author>
<pubDate>2008/9/18 9:12:36</pubDate>
<description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT color=#ff0000 size=5><STRONG>&nbsp;&nbsp;&nbsp; 数字万用表使用方法 <BR></STRONG></FONT>1． 准备 <BR>按下电源开关，观察液晶显示是否正常，有否电池缺电标志出现，若有则要先<BR>更换电池。 <BR>2． 使用 <BR>（1）&nbsp; 交、直流电流的测量 <BR>&nbsp;&nbsp;&nbsp;&nbsp; 根据测量电流的大小选择适当的电流测量量程和红表笔的插入孔，<BR>测量直流时，红表笔接触电压高一端，黑表笔接触电压低的一端，正向<BR>电流从红表笔流入万用表，再从黑表笔流出，当要测量的电流大小不清<BR>楚的时候，先用最大的量程来测量，然后再逐渐减小量程来精确测量。&nbsp; <BR>（2）&nbsp; 交、直流电压的测量 <BR>&nbsp;&nbsp;&nbsp;&nbsp; 红表笔插入“V/Ω”插孔中，根据电压的大小选择适当的电压测量<BR>量程，黑表笔接触电路“地”端，红表笔接触电路中待测点。特别要注<BR>意，数字万用表测量交流电压的频率很低（45～500Hz） ，中高频率信<BR>号的电压幅度应采用交流毫伏表来测量。 <BR>（3）&nbsp; 电阻的测量 <BR>&nbsp;&nbsp;&nbsp; 红表笔插入“V/Ω”插孔中，根据电阻的大小选择适当的电阻测量<BR>量程，红、黑两表笔分别接触电阻两端，观察读数即可。特别是，测量<BR>在路电阻时（在电路板上的电阻），应先把电路的电源关断，以免引起<BR>读数抖动。禁止用电阻档测量电流或电压（特别是交流 220V 电压），<BR>否则容易损坏万用表。 <BR>&nbsp;&nbsp;&nbsp;&nbsp; 另外，利用电阻档还可以定性判断电容的好坏。先将电容两极短路<BR>（用一支表笔同时接触两极，使电容放电），然后将万用表的两支表笔<BR>分别接触电容的两个极，观察显示的电阻读数。若一开始时显示的电阻<BR>读数很小（相当于短路），然后电容开始充电，显示的电阻读数逐渐增<BR>大，最后显示的电阻读数变为“1”（相当于开路） ，则说明该电容是好<BR>的。若按上述步骤操作，显示的电阻读数始终不变，则说明该电容已损<BR>坏（开路或短路）。特别注意的是，测量时要根电容的大小选择合适的<BR>电阻量程，例如 47μF用 200k 档，而 4.7μF则要用 2M 档等等。 <BR>（4）&nbsp; 二极管导通电压检测 <BR>&nbsp;&nbsp;&nbsp;&nbsp; 在这一档位，红表笔接万用表内部正电源，黑表笔接万用表内部负<BR>电源。&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;万用表显示二极管的正向导通电压，单位是 mV。通常好的硅二极管正向导通电压应为 500mV～800mV，好的锗二极管正向导通电压应为 200mV～300mV。<BR>假若显示“000”，则说明二极管击穿短路，假若显示“1”，则说明二极管正向不通。&nbsp;&nbsp;此档也可以用来判断三极管的好坏以及管脚的识别。测量时，先将<BR>一支表笔接在某一认定的管脚上，另外一支表笔则先后接到其余两个管<BR>脚上，如果这样测得两次均导通或均不导通，然后对换两支表笔再测，<BR>两次均不导通或均导通，则可以确定该三极管是好的，而且可以确定该<BR>认定的管脚就是三极管的基极。若是用红表笔接在基极，黑表笔分别接<BR>在另外两极均导通，则说明该三极管是 NPN 型，反之，则为 PNP 型。<BR>最后比较两个 PN 结正向导通电压的大小，读数较大的是 be 结，读数<BR>较小的是 bc结，由此集电极和发射极都识别出来了。&nbsp;<BR>（5）&nbsp; 三极管值β测试 <BR>&nbsp;&nbsp;&nbsp;&nbsp; 首先要确定待测三极管是 NPN 型还是 PNP 型，然后将其管脚正确<BR>地插入对应类型的测试插座中，功能量程开关转到β档，即可以直接从<BR>显示屏上读取β值，若显示“000”，则说明三极管已坏。 <BR>（6）&nbsp; 短路检测 <BR>&nbsp;&nbsp;&nbsp;&nbsp; 将功能、量程开关转到“·）））”位置，两表笔分别测试点，若有短<BR>路，则蜂鸣器会响。 <BR>&nbsp;<BR>五．注意事项 <BR>1． 注意正确选择量程及红表笔插孔。对未知量进行测量时，应首先把量程调到最<BR>大，然后从大向小调，直到合适为此。若显示“1”，表示过截，应加大量程。 <BR>2． 不测量时，应随手关断电源。 <BR>3． 改变量程时，表笔应与被测点断开。 <BR>4． 测量电流时，切忌过载。 <BR>5． 不允许用电阻档和电流档测电压。]]></description>
</item><item>
<title><![CDATA[四电压比较器LM339的8个典型应用例子]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=sccwqiang&amp;id=40025</link>
<author>sccwqiang</author>
<pubDate>2008/9/18 7:19:06</pubDate>
<description><![CDATA[
<DIV align=center><FONT color=#f70909 size=4><STRONG>四电压比较器LM339的8个典型应用例子</STRONG></FONT></DIV><BR><BR>LM339集成块内部装有四个独立的电压比较器，该电压比较器的特点是：1）失调电压小，典型值为2mV；2）电源电压范围宽，单电源为2-36V，双电源电压为±1V-±18V；3）对比较信号源的内阻限制较宽；4）共模范围很大，为0~（Ucc-1.5V）Vo；5）差动输入电压范围较大，大到可以等于电源电压；6）输出端电位可灵活方便地选用。<BR>　　LM339集成块采用C-14型封装，图1为外型及管脚排列图。由于LM339使用灵活，应用广泛，所以世界上各大IC生产厂、公司竟相推出自己的四比较器，如IR2339、ANI339、SF339等，它们的参数基本一致，可互换使用。<BR><IMG alt="" src="http://www.avrw.com/article/pic/20060711091404_1.gif" border=0><BR>　　LM339类似于增益不可调的运算放大器。每个比较器有两个输入端和一个输出端。两个输入端一个称为同相输入端，用“+”表示，另一个称为反相输入端，用“-”表示。用作比较两个电压时，任意一个输入端加一个固定电压做参考电压（也称为门限电平，它可选择LM339输入共模范围的任何一点），另一端加一个待比较的信号电压。当“+”端电压高于“-”端时，输出管截止，相当于输出端开路。当“-”端电压高于“+”端时，输出管饱和，相当于输出端接低电位。两个输入端电压差别大于10mV就能确保输出能从一种状态可靠地转换到另一种状态，因此，把LM339用在弱信号检测等场合是比较理想的。LM339的输出端相当于一只不接集电极电阻的晶体三极管，在使用时输出端到正电源一般须接一只电阻（称为上拉电阻，选3-15K）。选不同阻值的上拉电阻会影响输出端高电位的值。因为当输出晶体三极管截止时，它的集电极电压基本上取决于上拉电阻与负载的值。另外，各比较器的输出端允许连接在一起使用。&nbsp;<BR><BR><STRONG>单限比较器电路</STRONG> 
<P>　　图2a给出了一个基本单限比较器。输入信号Uin，即待比较电压，它加到同相输入端，在反相输入端接一个参考电压（门限电平）Ur。当输入电压Uin&gt;Ur时，输出为高电平UOH。图2b为其传输特性。<BR><IMG alt="" src="http://www.avrw.com/article/pic/20060711091404_2.gif" border=0><BR>　　图3为某仪器中过热检测保护电路。它用单电源供电，1/4LM339的反相输入端加一个固定的参考电压，它的值取决于R1于R2。UR=R2/（R1+R2）*UCC。同相端的电压就等于热敏元件Rt的电压降。当机内温度为设定值以下时，“+”端电压大于“-”端电压，Uo为高电位。当温度上升为设定值以上时，“-”端电压大于“+”端，比较器反转，Uo输出为零电位，使保护电路动作，调节R1的值可以改变门限电压，既设定温度值的大小。<BR><IMG alt="" src="http://www.avrw.com/article/pic/20060711091404_3.gif" border=0><BR><STRONG>&nbsp;迟滞比较器</STRONG> </P>
<P>　　迟滞比较器又可理解为加正反馈的单限比较器。前面介绍的单限比较器，如果输入信号Uin在门限值附近有微小的干扰，则输出电压就会产生相应的抖动（起伏）。在电路中引入正反馈可以克服这一缺点。<BR>　　图4a给出了一个迟滞比较器，人们所熟悉的“史密特”电路即是有迟滞的比较器。图4b为迟滞比较器的传输特性。<BR><IMG alt="" src="http://www.avrw.com/article/pic/20060711091404_4.gif" border=0><BR>　　不难看出，当输出状态一旦转换后，只要在跳变电压值附近的干扰不超过ΔU之值，输出电压的值就将是稳定的。但随之而来的是分辨率降低。因为对迟滞比较器来说，它不能分辨差别小于ΔU的两个输入电压值。迟滞比较器加有正反馈可以加快比较器的响应速度，这是它的一个优点。除此之外，由于迟滞比较器加的正反馈很强，远比电路中的寄生耦合强得多，故迟滞比较器还可免除由于电路寄生耦合而产生的自激振荡。<BR>　　如果需要将一个跳变点固定在某一个参考电压值上，可在正反馈电路中接入一个非线性元件，如晶体二极管，利用二极管的单向导电性，便可实现上述要求。图5为其原理图。<BR><IMG alt="" src="http://www.avrw.com/article/pic/20060711091404_5.gif" border=0><BR>　　图6为某电磁炉电路中电网过电压检测电路部分。电网电压正常时，1/4LM339的U4&lt;2.8V，U5=2.8V，输出开路，过电压保护电路不工作，作为正反馈的射极跟随器BG1是导通的。当电网电压大于242V时，U4&gt;2.8V，比较器翻转，输出为0V，BG1截止，U5的电压就完全决定于R1与R2的分压值，为2.7V，促使U4更大于U5，这就使翻转后的状态极为稳定，避免了过压点附近由于电网电压很小的波动而引起的不稳定的现象。由于制造了一定的回差（迟滞），在过电压保护后，电网电压要降到242-5=237V时，U4&lt;U3，电磁炉才又开始工作。这正是我们所期望的。<BR><IMG alt="" src="http://www.avrw.com/article/pic/20060711091404_6.gif" border=0>&nbsp;</P>
<P><STRONG>双限比较器（窗口比较器）</STRONG> </P>
<P>　　图7电路由两个LM339组成一个窗口比较器。当被比较的信号电压Uin位于门限电压之间时（UR1&lt;Uin&lt;UR2），输出为高电位（UO=UOH）。当Uin不在门限电位范围之间时，（Uin&gt;UR2或Uin&lt;UR1）输出为低电位（UO=UOL），窗口电压ΔU=UR2-UR1。它可用来判断输入信号电位是否位于指定门限电位之间。<BR><IMG alt="" src="http://www.avrw.com/article/pic/20060711091404_7.gif" border=0></P>
<P><STRONG>用LM339组成振荡器</STRONG> </P>
<P>　　图8为有1/4LM339组成的音频方波振荡器的电路。改变C1可改变输出方波的频率。本电路中，当C1=0.1uF时。f=53Hz；当C1=0.01uF时，f=530Hz；当C1=0.001uF时，f=5300Hz。<BR>　　LM339还可以组成高压数字逻辑门电路，并可直接与TTL、CMOS电路接口。<BR><IMG alt="" src="http://www.avrw.com/article/pic/20060711091404_8.gif" border=0></P>]]></description>
</item>
</channel>
</rss>