RSS 2.0 Feed
语言(Language)
摘要:在计算亲和数的时候,由于涉及到密集运算,有必要把计算工作转移到背景线程,以避免界面会失去响应。在.Net 1.0中,可以用ManualResetEvent、线程和Delegate的异步调用来实现,但是在.Net 2.0中,可以使用BackgroundWorker对象来简化这个工作。这个对象自动化了进度报告和终止线程的功能。 要使用这个对象来创建工作线程,首先需要加入一个BackgroundWorker对象到表单(Form)或者用户控件(UserControl),然后调用其RunWorkerAsync方法: private: System::Void AmicableNumberView_Load(System::Object^ sender, System::EventArgs^ e) ...{ propertyGrid->SelectedObject = Range; listViewPairs->VirtualListSize=0; timer->Start(); m_rAmicableNumberPairs->Clear(); backgroundWorker->RunWorkerAsync (Range); } 在线程创建之后会自动触发DoWork事件。这个事件中的处理类似于1.1中的线程函数体,可以通过访问DoWorkEventArgs参数的argument属性来访问在用RunWorkerAsync启动线程时传递的参数,以及调用ReportProgress定时报告进度。private: System::Void backgroundWorker_DoWork(System::Object^ sender, System::ComponentModel::DoWorkEventArgs^ e) ...{ CAmicableNumberRange range=(CAmicableNumberRange)e->Argument; int nNumbers=range.Max-range.Min; int nPercentComplete=0; m_rGenerator->Range=range; m_rGenerator->StartWork(); while(!backgroundWorker->CancellationPending && m_rGenerator->DoWork())...{ nPercentComplete = (int)( ......[阅读全文]

posted @ | Feedback (6) | Filed Under [ 用户界面 .Net Framework 类库(Library) 语言(Language) C++/CLI/Managed C++ Extension ]

摘要: 点此查看本文代码  相亲数(Amicable Pair),又称亲和数、友爱数,指两个正整数中,彼此的全部约数之和(本身除外)与另一方相等。 例如220与284: 220的全部约数(除掉本身)相加是:1+2+4+5+10+11+20+22+44+55+110=284 284的全部约数(除掉284本身)相加的和是:1+2+4+71+142=220 寻找指定范围内的相亲数的一个方法如下:对于范围内的每个数,用试除法获得约数,之后求和: int GetAmicableNumber(int nNumber) ...{ int nSumDivisors = SumDivisors(nNumber); if (nSumDivisors == nNumber) return 0;//perfect number if (nNumber == SumDivisors(nSumDivisors)) return nSumDivisors; return 0; } int SumDivisors(int n) ...{ ......[阅读全文]

posted @ | Feedback (9) | Filed Under [ .Net Framework 语言(Language) C++/CLI/Managed C++ Extension ]

摘要:一个算法的优化的相关代码// Amicable.h #pragma once #include "WinFormThread.h" using namespace System; using namespace System::Collections::Generic; /**//// <summary> /// Amicable Number Generator /// Search a range for amicable pairs. /// </summary> namespace Amicable ...{ /**//// <summary> /// An amicable pair consists of two distinct integers /// for which the sum of proper divisors (the divisors excluding the number itself) ///......[阅读全文]

posted @ | Feedback (1) | Filed Under [ .Net Framework 语言(Language) C++/CLI/Managed C++ Extension ]

摘要: C语言中并未规定char、int和long这样的基本类型的长度和符号。这给与了编译器很大的灵活性,但是也产生了很多问题。 int是程序中最常用的类型。理论上来说,int应该被定义为CPU中运算最快的类型,比如80386系列中的32位整数。在升级程序到64位CPU环境的时候,应该可以重新编译程序来把32位运算升级到64位运算以增加性能。但是太多代码不正确地使用int和long来做指针运算,以至于会在升级时崩溃。目前很多64位编译器中的int仍然是32位,在有的编译器中甚至连long也仍旧是32位,而引入新的数据类型来代表64位变量。 另外一个问题是基本类型的符号。在Visual C++中,基本类型是有符号的,如果在开发时使用无符号修饰符的基本类型的话,这会在移植程序到使用无符号基本类型的编译器时出现问题。举例来说,在基本类型的符号不同的情况下,下面两行代码int b=-1;unsigned int a=b; int b=-1;b>>5; 的行为会有所不同。Visual C++ 2005编译器开发人员试图关闭/J开关(这个开关决定char是unsigned还是signed),并且用改进的警告功能来在编译未指定符号的基本类型时给出警告信息。但是这会使得绝大多数代码工作不正常,用户的负面反馈淹没了这个动议。 为了代码的可移植性起见,建议在使用基本类型的时候加上符号修饰符。...[阅读全文]

posted @ | Feedback (4) | Filed Under [ 编译(CodeGen) 语言(Language) ]

摘要:好长时间没更新BLOG了,向大家拜个晚年先。最近没怎么写代码,转几篇在网易虚拟社区发的文章过来充数。 对于BUG的自信 Donald E. Knuth(高德纳)在TeX: The Program的前言中说:"我相信,在1985年11月27日,TeX代码里面的最后一个BUG已经被发现和解决了。但是,如果代码中仍旧有BUG,我很高兴付给任何第一个发现BUG的人20.48美元(这是前一个金额的两倍,而且我计划在一年内把它翻倍。你看,我很自信!)" 想知道后来发生了什么吗?在http://truetex.com/knuthchk.htm可以看到他写出去的支票的金额是从2.56美元开始翻倍的。微基百科中关于这种支票的文章(http://en.wikipedia.org/wiki/Knuth_reward_check)说,截至2001年10月为止,他写出去了超过两千张这样的支票,但是他的BUG支票是如此有名,以至于很多人把他的支票收藏起来而不是拿出去兑现(http://www.tug.org/whatis.html)。有多少程序员在发布产品的时候可以这样自信地声明产品没有问题? 遗憾的是,现在的程序员经常把发现BUG的责任推给测试人员——“不用担心,测试人员会发现所有BUG的,这是他们的工作”。实际上,测试人员并没有开发人员的条件,他们不可能进行源代码级别的调试,很大程度上只能靠运气——没错,是靠运气,如果一个BUG很容易被发现,程序员不太可能自己没有发现它——来发现BUG。 还有一些人干脆就认为BUG是不可避免的,或者认为不值得这么精益求精(参见网易虚拟社区http://p5.club.163.com/viewArticleByWWW.m?boardId=clanguage&articleId=clanguage_108eacc622169e7&boardOffset=0的讨论),但是实际上防止BUG出现的最好的时机,就是在编写代码的时候。在编写代码一段时间之后,即使是编写者本人也可能需要一段时间来理解代码(如果不习惯写注释的话,这段时间会更长),更别说定位问题所在了。在编写代码时,如果具有良好的习惯,可以免去很多在之后消灭BUG的困难。 规范不是语法 太多人把不要使用goto奉为圣旨,从来不想去打破。他们会争论,goto会造成难以维护的难读的代码,以及使编译器无法进行优化。这两点在很大程度上是真的,但是也有使用goto可以增加程序可读性和效率时候。在这种情况下,遵循“不使用goto语句”规范会产生更糟糕的代码。一些人喜欢在成员函数后面加const,但是另外一些人没有养成这个习惯。一个直接的结果就是,一些看起来对对象完全没有影响的函数不能在const函数里面使用。这时候应该怎么办?看看Paul DiLascia建议的,把this指针强行转化为一个非const指针(http://www.microsoft.com/msj/archive/S126E.aspx)。如果函数实际上会对对象成员造成影响(例如CToolBar::GetItemRect),这也会带来潜在危险。为了和ANSI标准之前编写的代码兼容,ANSI C中的memchr函数的声明为void *memchr( const void *buf, int c, size_t count ); 这里c是一个字符。很明显,标准为了兼容性放弃了明确性和更强的类型检查。如果放弃兼容性,这个函数应该声明为如下形式void *memchr( const void *buf, unsigned char c, size_t count ); 微软的很多代码使用一种叫做匈牙利表示法的命名规范。这使得标识符的含义和类型更加明确——但是这是从广义的角度来说的。考虑如下函数声明char *strcpy( char *strDestination, const char *strSource ); 如果严格遵循原始的匈牙利表示法,那么两个参数的声明应该是pch开头。但是以str开头给这两个参数更多含义:它们指向以\0为结束符的字符串。   规范是用来在大部分时间里遵循,以及在可以得到更好的结果时打破的。 编译警告的意义 智能化的编译器开始将语法正确的语句列为警告:while(size-->0);//注意这里有个分号 *pTo++=*pFrom++; 编译器会报告空循环问题。但是对于以0结尾的字符串复制while(*pTo++=*pFrom++); ,这样的警告是多余的。更加常见的警告是在条件判断语句中if(ch='\0') EndOfString(); 为了绕过这个警告,需要添加额外的运算或者语句,或者更正错误的赋值。while((*pTo++=*pFrom++)!='\0')...{} if(ch=='\0') 一些程序员甚至将比较语句修改成if('\0'==ch) 这样作的原因显而易见:为了减少潜在的BUG。如果你的编译器没有这样的警告,那么你可以使用一些工具来检查那些语法正确但是有潜在BUG的代码。LintProject (http://www.codeproject.com/tools/lintproject.asp)就是其中一个。但是,良好的编程习惯还是减少BUG出现的最好的方法。在觉得警告消息太烦人的时候,不妨想想编译器的开发人员为什么要编写这么多警告消息,而不是仅仅寻求关闭警告的方法。 P.S. Visual C++的默认警告等级是3级。发布软件之前应该改成4级,之后检查所有的编译警告。 无处不在的断言 使用编译器来捕获BUG的主意很好,Visual Studio 2005甚至会报告定义的变量不符合命名规范(Warning 1 CA1709 : Microsoft.Naming : Correct the casing of type name 'welcome'.);但是我敢打赌你检查BUG列表的时候,你会发现只有一小部分BUG会被编译器抓到。很多BUG在程序运行过程中很少会出现,例如内存分配失败的问题using namespace System; #define ARRAY_SIZE 1000 struct bubbleBase ...{ int value; }; class bubble1:public bubbleBase ...{ public: virtual int getvalue()...{return value;} virtual void setvalue(int newvalue)...{value=newvalue;} }; class bubble2:public bubbleBase ...{ public: virtual int __clrcall getvalue()...{return value;} virtual void __clrcall setvalue(int newvalue)...{value=newvalue;} }; template<class T> void bubbleSort(int length) ...{ TimeSpan ts; T* array1=new T[ARRAY_SIZE]; for (int i=0;i<ARRAY_SIZE ;i++) ...{ array1[i].setvalue(ARRAY_SIZE-i-1); } ......[阅读全文]

posted @ | Feedback (1) | Filed Under [ 随笔 .Net Framework 编译(CodeGen) 类库(Library) 语言(Language) C++/CLI/Managed C++ Extension ]

摘要:C#程序员可以用三个斜杠来开始XML格式的注释,而且编译器可以据此生成可用于自动生成帮助文档的XML文件。Visual C++ 2005中的编译器也支持了这个功能,而且对非托管函数也生效,前提是必须打开/clr和/DOC开关,并且不能使用/clr:oldSyntax开关编译。/**//// ///Use two bubble sort steps ///to show the performance information ///of different function calls. /// int main(array<System::String ^> ^args) ...{ bubbleSort<bubble1>(ARRAY_SIZE); bubbleSort<bubble2>(ARRAY_SIZE); return 0; } #pragma unmanaged /**//// ///testing unmanaged function... /// int foo() ...{ return 0; } 有空的话,多去微软的反馈中心提提对产品的建议是很有好处的…… 参考 /doc (Process Documentation Comments) (C/C++)( http://msdn2.microsoft.com/en-us/library/ms173501.aspx ) XML Comments for Managed C++ Applications (http://www.codeproject.com/dotnet/MCXDoc.asp) NDoc Code Documentation Generator for .NET(http://ndoc.sourceforge.net)...[阅读全文]

posted @ | Feedback (3) | Filed Under [ 编译(CodeGen) 集成开发环境(IDE) 语言(Language) C++/CLI/Managed C++ Extension ]

摘要:个人觉得这次MVP峰会最大的进步就是技术相关的Session数量大大增加,按照MVP专长来分类;而不像上次那样按主题分类。我只需要在VC产品组的日程里面选择就可以了,而不是像上回那样不得不去听移动开发。当然这回也有MVP不去参加VC的Session,跑去听IE和移动开发。内容方面也比上次活泼很多,Don Box还是那么幽默,比尔·盖茨也有搞笑的演出,不过他看起来比去年七月份在北京的时候老多了。 一些可能有人会感兴趣的技术信息 新的产品开发合作网站http://connect.microsoft.com/。在这里可以申请参与新产品的测试。软件开发者可以使用Windows错误报告机制(Windows Error Reporting,简称WER,https://winqual.microsoft.com/parentorgs.asp)来获得反馈。 有人正在开发把VC项目转化成MSBuild的XML格式的工具 (http://blogs.msdn.com/clichten/archive/2005/06/07/Building_VC_projects_with_msbuild_and_not_using_vcbuild.aspx)。关于MSBuild的概述可以看看Christophe Nasarre的文章Overview of MSBuild (http://msdn.microsoft.com/library/en-us/dnlong/html/msbuildpart1.asp)和MSBuild Team Blog (http://blogs.msdn.com/msbuild)。还不知道这个工具是否支持VS.Net中其他语言的项目。新的代号为Phoenix的统一编译器平台也在计划中。可以加入插件来实现自定义语言的编译器 (http://blogs.msdn.com/kangsu/archive/2005/08/11/450481.aspx)。 在MFC8.0中使用Windows Forms会更加简单,加速键和Tab键的处理现在可以扔给MFC来做了 (http://blogs.msdn.com/yvesdolc/archive/2005/04/26/WindowsForms_In_MFC.aspx)。VC8.0中也会有一些新的向导,例如单元测试工程向导 (http://msdn.microsoft.com/library/en-us/dnvs05/html/vs05security.asp)。 一些建议 停止开发新的面向Win9x的程序和静态链接MFC的程序。使用新的MFC版本编译旧的程序来增加应用程序的安全性。 在新的程序中使用Unicode编码,同时尽可能将现有程序移植到Unicode。 移植到Visual C++ 2005来使用强大的编译器和调试器。 尽管限于保密协议我不能说得更多,但是微软在11月7号就会正式发布Visual Studio 2005、SQL Server 2005和BizTalk Server 2006了。新的Visual Studio版本(代号Orca和Hawaii)也正在规划中。...[阅读全文]

posted @ | Feedback (8) | Filed Under [ 用户界面 .Net Framework 集成开发环境(IDE) 类库(Library) 平台SDK(Platform SDK) 文档(Documentation) 语言(Language) ]

摘要:Hook DHTML Commands 浏览器在执行很多命令之前都会允许容器来替换默认的处理。在执行一些默认的命令之前,系统会查询用户对IDocHostUIHandler的实现对象的IOleCommandTarget接口,调用默认(NULL)或者CGID_DocHostCommandHandler命令组的命令。如果容器的对应命令处理返回S_OK。那么默认的处理就不会被调用。 下面列出一些可以在容器中自定义的操作:(这些常量的定义位于docobj.h中) OLECMDID_PRINT,默认命令组 OLECMDID_SHOWSCRIPTERROR, CGID_DocHostCommandHandler命令组 OLECMDID_FOCUSVIEWCONTROLSQUERY, CGID_DocHostCommandHandler命令组 OLECMDID_SHOWPAGEACTIONMENU, CGID_DocHostCommandHandler命令组 MFC提供了一些比较容易扩展的类和宏,这样可以很容易地在扩展容器来实现新的接口。这里使用CCmdTarget类提供的GetInterfaceHook虚函数来进行扩展。 //This sample is based on MFC sample DHTMLExplore. //a button is inserted into explore.htm: //<BUTTON class=hotElement id=print accesskey="P"><U>P</U>rint</BUTTON> //to invoke the print command #include <afxole.h> #include <mshtmcid.h> ///////////////////////////////////////////////////////////////////////////// // CDHtmlExploreDlg dialog class CDHtmlExploreDlg; //customize the CBrowserControlSite class to implement IOleCommandTarget. //the IDocHostUIHandler interface is implemented in CBrowserControlSite, //an internal control site class declared within afxdhtml.h class CDHtmlExploreControlSite: public CBrowserControlSite , public IOleCommandTarget CDHtmlExploreControlSite( COleControlContainer* pCtrlCont, CDHtmlExploreDlg *pHandler) : CBrowserControlSite(pCtrlCont,pHandler){}; protected: // Implementation ......[阅读全文]

posted @ | Feedback (6) | Filed Under [ 用户界面 HTML编程(IE Programming) 集成开发环境(IDE) 脚本(Scripting) 类库(Library) 平台SDK(Platform SDK) 语言(Language) ]

摘要:使用WinDbg调试VC程序 虽然在VC6.0中可以通过安装Visual C++ Toolkit(网站:http://msdn.microsoft.com/visualc/vctoolkit2003/)来编写基于最新版本的平台SDK、DirectX SDK的程序以及托管代码,但是VC6附带的调试器并不支持新版本的调试信息,所以实际上是不能用VC6来调试新版本编译器生成的程序的。一个替代的解决方案是使用新版本的Windows调试工具Windbg(网站:http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx)。Windbg的调试功能基本和Visual C++中的相同,但是需要手动设定源文件和调试符号文件的搜索路径(可以参考VC6.0中的对应设置)。一些代码,例如MFC的代码比较难于定位,这时可以双击调用堆栈中的函数名称来打开文件并定位到函数所在位置。Windbg可以进行有限的托管代码调试,但是调试过程比较麻烦。在没有安装Visual Studio的计算机上调试,例如进行远程调试的时候可能还需要部署调试符号(Generating and Deploying Debug Symbols With Visual C++ 6.0)。 调试Visual Studio .Net 的程序需要用户是管理员或者"Debug User"用户组成员。如果登录用户不是该组成员,那么也可以用WinDbg来调试程序。...[阅读全文]

posted @ | Feedback (2) | Filed Under [ 随笔 .Net Framework 安全和管理(Security and Management) 调试技巧(Debugging) 工具(Tools) 集成开发环境(IDE) 类库(Library) 平台SDK(Platform SDK) 文档(Documentation) 语言(Language) C++/CLI/Managed C++ Extension ]

Full 语言(Language) Archive