??xml version="1.0" encoding="utf-8" standalone="yes"?>国产精品美女久久久免费,麻豆av久久av盛宴av,99久久久精品http://www.shnenglu.com/justin-shi/category/6151.html<font>&nbsp;</font> zh-cnWed, 20 May 2009 18:20:12 GMTWed, 20 May 2009 18:20:12 GMT60再谈异常――谈C++与Object Pascal中的构造函C异常 http://www.shnenglu.com/justin-shi/archive/2009/05/20/83429.htmlq幽q幽Tue, 19 May 2009 16:42:00 GMThttp://www.shnenglu.com/justin-shi/archive/2009/05/20/83429.htmlhttp://www.shnenglu.com/justin-shi/comments/83429.htmlhttp://www.shnenglu.com/justin-shi/archive/2009/05/20/83429.html#Feedback1http://www.shnenglu.com/justin-shi/comments/commentRss/83429.htmlhttp://www.shnenglu.com/justin-shi/services/trackbacks/83429.html再谈异常――谈C++与Object Pascal中的构造函C异常

作者:(x)Nicrosoft(nicrosoft@sunistudio.com) 2001.9.15
个h主页Qhttp://www.sunistudio.com/nicrosoft/
东日文档Qhttp://www.sunistudio.com/asp/sunidoc.asp

  我们知道Q类的构造函数是没有q回值的Q如果构造函数构造对象失败,不可能依靠返回错误代码。那么,在程序中如何标识构造函数的p|呢?最“标准”的方法就是:(x)抛出一个异常?/p>

  构造函数失败,意味着对象的构造失败,那么抛出异常之后Q这?#8220;半死不活”的对象会(x)被如何处理呢Q这是本文的主题?/p>

在C++中,构造函数抛出异常后Q析构函C?x)被调用。这是合理的Q因为此时对象ƈ没有被完整构造。也是_(d)如果构造函数已l做了一些诸如分配内存? 打开文g{操作的话,那么c需要有自己的成员来C做过哪些动作。在C++中,l典的解x案是使用STL的标准类auto_ptrQ这在每一本经? C++著作中都有介l,我在q里׃多说了。在q里Q我惛_介绍一U?#8220;非常?#8221;的方式,其思想是避免在构造函C抛出异常。我们可以在cM增加一? Init(); 以及 UnInit();成员函数用于q行Ҏ(gu)产生错误的资源分配工作,而真正的构造函C先将所有成员置为NULLQ然后调? Init(); q判断其q回|或者捕?Init()抛出的异常)Q如果Init();p|了,则在构造函C调用 UnInit(); q设|一个标志位表明构造失败。UnInit()中按照成员是否ؓ(f)NULLq行资源的释攑ַ作。示例代码如下:(x)
class A
{
private:
 char* str;
 int failed;

public:
 A();
 ~A();
 int Init();
 int UnInit();
 int Failed();
};

A::A()
{
 str = NULL;
 try
 {
  Init();
  failed = 0;
 }
 catch(...)
 {
  failed = 1;
  UnInit();
 }
}

A::~A()
{
 UnInit();
}

int A::Init()
{
 str = new char[10];
 strcpy(str, "ABCDEFGHI");
 throw 10;

 return 1;
}

int A::UnInit()
{
 if (!str)
 {
  delete []str;
  str = NULL;
 }

 printf("Free Resource

");
 return 1;
}

int A::Failed()
{
 return failed;
}

int main(int argc, char* argv[])
{
 A* a = new A;
 if ( a->Failed() )
  printf("failed

");
 else
  printf("succeeded

");

 delete a;

 getchar();
 return 0;
}

  你会(x)发现Q在int A::Init()中包含了throw 10;的代码(产生一个异常,模拟错误的发生)Q执行结果是Q?br>  Free Resource
  failed
  Free Resource
  虽然 UnInit();被调用了两次Q但是由于UnInit();中做了判断(if (!str)Q,因此不会(x)发生错误。而如果没有发生异常(L int A::Init()中的throw 10;代码Q,执行l果是:(x)
  Succeeded
  Free Resource
  和正常的程没有M区别?/p>

在Object PascalQDelphi/VCLQ中Q这个问题就变得非常的简单了Q因?OP Ҏ(gu)造函数的异常的处理与C++不同Q在Create时抛出异常后Q编译器?x)自动调用析构函数DestroyQƈ且会(x)判断哪些资源被分配了Q实行自动回 收。因此,其代码也变得非常z,如下Q?br>type
  A = class
  private
  str : PChar;
  public
  constructor Create();
  destructor Destroy(); override;
  end;

constructor A.Create();
begin
  str := StrAlloc(10);
  StrCopy(str, 'ABCDEFGHI');
  raise Exception.Create('error');
end;

destructor A.Destroy();
begin
  StrDispose(str);
  WriteLn('Free Resource');
end;

var oa : A;
  i : integer;
begin
  try
      oa := A.Create();
      WriteLn('Succeeded');
      oa.Free();
  except
      oa := nil;
      WriteLn('Failed');
  end;

  Read(i);
end.

  在这D代码中Q如果构造函数抛出异常(即Create中含有raise Exception.Create('error');Q,执行的结果是Q?br>  Free Resource
  Failed
  此时?#8220;Free Resource”输出是由~译器自动调用析构函数所产生的。而如果构造函数正常返回(即不抛出异常Q,则执行结果是Q?br>  Succeeded
  Free Resource
  此时?#8220;Free Resource”输出是由 oa.Free()的调用生的?/p>

lgQC++与Object Pascal对于构造函数抛出异常后的不同处理方式,其实正是两种语言的设计思想的体现。C++U承C的风|注重效率Q一切交l程序员来掌握,~译器不 作多余动作。Object Pascall承Pascal的风|注重E序的美学意义(不可否认QPascal代码是全世界最优美的代码)Q编译器帮助E序员完成复杂的工作。两U语 a都有存在的理由,都有存在的必要!而掌握它们之间的差别Q能让你更好地控制它们,辑ֈ自由的理想王国?/p>




q幽 2009-05-20 00:42 发表评论
]]>
[GDI+]如何一个彩色图像{换成黑白囑փhttp://www.shnenglu.com/justin-shi/archive/2008/10/20/64484.htmlq幽q幽Mon, 20 Oct 2008 05:10:00 GMThttp://www.shnenglu.com/justin-shi/archive/2008/10/20/64484.htmlhttp://www.shnenglu.com/justin-shi/comments/64484.htmlhttp://www.shnenglu.com/justin-shi/archive/2008/10/20/64484.html#Feedback0http://www.shnenglu.com/justin-shi/comments/commentRss/64484.htmlhttp://www.shnenglu.com/justin-shi/services/trackbacks/64484.html彩色囑փ转换为黑白图像时需要计图像中每像素有效的亮度|通过匚w像素

亮度值可以轻松{换ؓ(f)黑白囑փ?/p>

计算像素有效的亮度值可以用下面的公式Q?/p>

Y=0.3RED+0.59GREEN+0.11Blue

然后使用 Color.FromArgb(Y,Y,Y) 来把计算后的D{?/p>

转换代码可以使用下面的方法来实现Q?br>C#

 1public Bitmap ConvertToGrayscale(Bitmap source)
 2
 3{
 4
 5  Bitmap bm = new Bitmap(source.Width,source.Height);
 6
 7  for(int y=0;y<bm.Height;y++)
 8
 9  {
10
11    for(int x=0;x<bm.Width;x++)
12
13    {
14
15      Color c=source.GetPixel(x,y);
16
17      int luma = (int)(c.R*0.3 + c.G*0.59+ c.B*0.11);
18
19      bm.SetPixel(x,y,Color.FromArgb(luma,luma,luma));
20
21    }

22
23  }

24
25  return bm;
26
27}

VB
 1Public Function ConvertToGrayscale()Function ConvertToGrayscale(ByVal source As Bitmap) as Bitmap
 2
 3  Dim bm as new Bitmap(source.Width,source.Height)
 4
 5  Dim x
 6
 7  Dim y
 8
 9  For y=0 To bm.Height
10
11    For x=0 To bm.Width
12
13      Dim c as Color = source.GetPixel(x,y)
14
15      Dim luma as Integer = CInt(c.R*0.3 + c.G*0.59 + c.B*0.11)
16
17      bm.SetPixel(x,y,Color.FromArgb(luma,luma,luma)
18
19    Next
20
21  Next
22
23  Return bm
24
25End Function


q幽 2008-10-20 13:10 发表评论
]]>
解析#pragma指ohttp://www.shnenglu.com/justin-shi/archive/2008/08/19/59319.htmlq幽q幽Tue, 19 Aug 2008 03:01:00 GMThttp://www.shnenglu.com/justin-shi/archive/2008/08/19/59319.htmlhttp://www.shnenglu.com/justin-shi/comments/59319.htmlhttp://www.shnenglu.com/justin-shi/archive/2008/08/19/59319.html#Feedback0http://www.shnenglu.com/justin-shi/comments/commentRss/59319.htmlhttp://www.shnenglu.com/justin-shi/services/trackbacks/59319.html
在所有的预处理指令中Q?Pragma 指o可能是最复杂的了Q它的作用是讑֮~译器的状态或者是指示~译器完成一些特定的动作?pragma指oҎ(gu)个编译器l出了一个方?在保持与C和C++语言完全兼容的情况下,l出L或操作系l专有的特征。依据定?~译指示是机器或操作pȝ专有?且对于每个编译器都是不同的?br>其格式一般ؓ(f): #Pragma Para
其中Para 为参敎ͼ下面来看一些常用的参数?br>
(1)message 参数?Message 参数是我最喜欢的一个参敎ͼ它能够在~译信息输出H?br>口中输出相应的信息,q对于源代码信息的控制是非常重要的。其使用Ҏ(gu)为:(x)
#Pragma message(“消息文本”)
当编译器遇到q条指o时就在编译输出窗口中消息文本打印出来?br>当我们在E序中定义了许多宏来控制源代码版本的时候,我们自己有可能都?x)忘记有没有正确的设|这些宏Q此时我们可以用q条指o在编译的时候就q行查。假设我们希望判断自己有没有在源代码的什么地方定义了_X86q个宏可以用下面的方?br>#ifdef _X86
#Pragma message(“_X86 macro activated!”)
#endif
当我们定义了_X86q个宏以后,应用E序在编译时׃(x)在编译输出窗口里昄“_
X86 macro activated!”。我们就不会(x)因ؓ(f)不记得自己定义的一些特定的宏而抓x腮了
?br>
(2)另一个用得比较多的pragma参数是code_seg。格式如Q?br>#pragma code_seg( ["section-name"[,"section-class"] ] )
它能够设|程序中函数代码存放的代码段Q当我们开发驱动程序的时候就?x)用到它?br>
(3)#pragma once (比较常用Q?br>只要在头文g的最开始加入这条指令就能够保证头文件被~译一ơ,q条指o实际上在VC6中就已经有了Q但是考虑到兼Ҏ(gu)ƈ没有太多的用它?br>
(4)#pragma hdrstop表示预编译头文g到此为止Q后面的头文件不q行预编译。BCB可以预编译头文g以加快链接的速度Q但如果所有头文g都进行预~译又可能占太多盘I间Q所以用这个选项排除一些头文g?
有时单元之间有依赖关p,比如单元A依赖单元BQ所以单元B要先于单元A~译。你可以?pragma startup指定~译优先U,如果使用?pragma package(smart_init) QBCB׃(x)Ҏ(gu)优先U的大小先后~译?

(5)#pragma resource "*.dfm"表示?.dfm文g中的资源加入工程?.dfm中包括窗?br>外观的定义?

(6)#pragma warning( disable : 4507 34; once : 4385; error : 164 )
{h(hun)于:(x)
#pragma warning(disable:4507 34) // 不显C?507?4可告信?br>#pragma warning(once:4385) // 4385可告信息仅报告一?br>#pragma warning(error:164) // ?64可告信息作Z个错误?br>同时q个pragma warning 也支持如下格式:(x)
#pragma warning( push [ ,n ] )
#pragma warning( pop )
q里n代表一个警告等U?1---4)?br>#pragma warning( push )保存所有警告信息的现有的警告状态?br>#pragma warning( push, n)保存所有警告信息的现有的警告状态,q且把全局警告
{讑֮为n?
#pragma warning( pop )向栈中弹出最后一个警告信息,在入栈和出栈之间所作的
一切改动取消。例如:(x)
#pragma warning( push )
#pragma warning( disable : 4705 )
#pragma warning( disable : 4706 )
#pragma warning( disable : 4707 )
//.......
#pragma warning( pop )
在这D代码的最后,重新保存所有的警告信息(包括4705Q?706?707)?br>Q?Qpragma comment(...)
该指令将一个注释记录放入一个对象文件或可执行文件中?br>常用的lib关键字,可以帮我们连入一个库文g?




q幽 2008-08-19 11:01 发表评论
]]>
pe的格?译)http://www.shnenglu.com/justin-shi/archive/2008/07/28/57323.htmlq幽q幽Sun, 27 Jul 2008 20:04:00 GMThttp://www.shnenglu.com/justin-shi/archive/2008/07/28/57323.htmlhttp://www.shnenglu.com/justin-shi/comments/57323.htmlhttp://www.shnenglu.com/justin-shi/archive/2008/07/28/57323.html#Feedback0http://www.shnenglu.com/justin-shi/comments/commentRss/57323.htmlhttp://www.shnenglu.com/justin-shi/services/trackbacks/57323.html

q幽 2008-07-28 04:04 发表评论
]]>
难以忘怀的WatcomQ{《Borland传奇》)http://www.shnenglu.com/justin-shi/archive/2008/07/26/57224.htmlq幽q幽Sat, 26 Jul 2008 03:52:00 GMThttp://www.shnenglu.com/justin-shi/archive/2008/07/26/57224.htmlhttp://www.shnenglu.com/justin-shi/comments/57224.htmlhttp://www.shnenglu.com/justin-shi/archive/2008/07/26/57224.html#Feedback0http://www.shnenglu.com/justin-shi/comments/commentRss/57224.htmlhttp://www.shnenglu.com/justin-shi/services/trackbacks/57224.html
const DWORD ALIGN_CORRECTION    =0x1000;// this big value is e.g. needed for WATCOM compiled files
上网一查,发现WATCOM竟然有这样一D传奇:(x)


一、Watcom的发展史

        在编译器h的时代,一家加拿大的小公司出品了Watcom C/C++~译器,但是以在DOS下能够生最?jng)_E序代码d于世的,许多写游戏和DOS Extender的厂商都指名要用Watcom C/C++Q因Z论是Borland C/C++q是Visual C/C++Q它们生的最?jng)_E序代码都比Watcom C/C++的最?jng)_E序代码差上一截。再加上当时最有名的DOS Extender厂商PharLap公司也是使用Watcom C/C++Q因此Watcom C/C++在当时专业的C/C++E序员以及系l程序员心中是第一品牌的C/C++开发工兗?

       Watcom C/C++在DOS市场站稳了脚跟之后,׃Windows已经逐渐成ؓ(f)市场的主,DOS势必被逐渐淘汰出局Q因此,W(xu)atcom C/C++如果要l生存下去,也就一定要推出Windowsq_的C/C++开发工兗大U是?993?994q左叻IW(xu)atcoml于推出W一个Windows下的C/C++开发工兗?

       不过Q当时Watcom C/C++在Windows推出的C/C++开发工具实在是qxE无奇。其集成开发环境和另外三个Ҏ(gu)比较h直像是远古的产品Q一点特色都没有。不qWatcom C/C++仍然是以它的最?jng)_~译器作为号召。因此当时发生了一个非常有的现象Q那是许多软g公司?x)同时买Borland C/C++Q或是Visual C/C++QSymantec C/C++之一Q再搭配一套Watcom C/C++。在开发应用系l时使用其他三套开发工具之一Q最后要时再使用Watcom C/C++来编译以产生最佳的E序代码?

       在Watcom C/C++推出了Windowsq_的开发工具之后,也吸引了一用者。虽然Watcom C/C++的市场比起其他的三家来说是最的Q但是ȝ撑v了一片天Q成为四大C/C++开发工具之一。稍后Watcom C/C++被Sybaseq购Q成为Sybase的Optima++的前w?

二、石破天惊还是巨星陨?

       1996q左叻ISybaseq购了Watcom之后l于推出了石破天惊的C/C++开发工P(x)Optima++。Optima++是当初结合了Watcom的最?jng)_~译器以及类似Delphi的组件拖曛_发环境的W一个RAD C/C++开发工兗更的是Optima++的组件架构(cMDelphi的VCLQ完全是以纯正的C/C++E序代码撰写的。这可不得了Q因代表Optima++是一个融合了Visual C/C++和Delphi两大王者开发工具ؓ(f)一w的赛亚人工兗?

       在我Q《Borland传奇》作者李l_(d)下同Q知道这个工兗ƈ且尝试实际用之后,极ؓ(f)震惊。因为对于我q个使用了C/C++ 五六q的人来_(d)它比Delphi更具有吸引力。因此我立刻在《RUN!PC》上介绍了这个不可置信的工具。果ӞOptima++很快开始风靡市场,虽然没有立刻占据很大的市Z额,但是已经造成了一股气势,开始ؓ(f)Visual C/C++和Delphi带来压力?

       我记得当时台湾Sybase办的产品发表?x)也吸引了数百h与会(x)Q不可一世。我的文章在《RUN!PC?上发表之后,台湾的Sybase立刻和我联络Q由当时的余协理和我见面Q也是希望我l箋为Optima++写文章,台湾Sybase也提供额外一字加2元稿费的待遇。但是我告诉余协理,Optima++ 1.0虽然很棒Q但是仍然有一些臭虫,而且和中文环境相冲突Q无法处理中文,需要立刻解册个问题才能够在台湄市场成功。她{应我立dd司反映。我也老实地告诉她Q在问题没有解决之前Q我无法写一些不实的东ѝ后来台湾Borland的ȝ理方先生也找我去询问有关Optima++的事情,我告诉他Optima++是好东西Q但是中文有问题。如果中文问题能够解冻I那么对Borland和Microsoft的品有很大的媄响,当时我还不知道Borland׃Optima++的媄响,已经开始准备开发C++ Builder?

       ?996q底左右吧,Optima++ 1.5l于q入Beta的阶Dc但是在我拿到Beta版时非常失望Q因Z文的问题仍然没有解决。后来台湾Sybase又找我去Q这ơ和我见面的是台湾Sybaseȝ理郭俊男先生Q以及Sybase的新加坡技术总裁Q不q我忘记q位先生的名字了。见了面之后Q我立刻把Optima++ 1.5中文的问题以及许多的臭虫告诉他们Q希望他们能够解冻I如此Optima++ 1.5才能够在中文市场成功。可是出乎我意料之外的是Q他们似乎ƈ不着急这些问题,反而询问我是否有意愿ؓ(f)Sybase工作Q做PowerBuilder的品经理?

       也许是因为我为Delphi写了太多的东西,让PowerBuilder在台湑֏了很大的影响Q因此他们希望我到Sybase工作Q以打击Delphiq且Promote PowerBuilder。当时他们提出的待遇条g实在是非常、非常的׃hQ比我当时的薪水高出一倍左叻I我当时在资策?x)工作)。不q由于我对PowerBuilder实在没有什么兴,因此我告诉他们,如果是做Optima++的品经理,那么我将?x)考虑q且接受?

       没有惛_QSybase的新加坡技术总裁告诉我Optima++?.5推出之后可能会(x)停止Q因为Sybase要把资源Ud为当时愈来愈U的Java研发一个新的Java RAD开发工P那就是后来的PowerJ。于是他询问我如果不愿意做PowerBuilder的品经理,那么是不是愿意做PowerJ的品经理?׃当时我已l知道Borland开始了Open JBuilder的研发,而我对Open JBuilder的兴远大于PowerJQ因此没有答应Sybase。果Ӟ在Optima++ 1.5推出之后Q不但中文的问题没有解决QSybase之后也没有l对Optima++研发下去?

       Optima++一个如此有潜力的品就q样消失了,真是令h遗憾。Optima++应该有很好的Z(x)可以成功。我怿Q如果当时Sybase知道C++ Builder后来的成果,可能׃?x)放弃Optima++了,而C/C++的RAD工具一直要到后来的C++ Builder来完成这个梦?

       xQ和Visual C/C++竞争的只有Borland的编译器了,然而虽然后来Borlandl箋推出了Borland C/C++ 5.0Q但是品质仍然不够好Q市场反应也不佳。后来终于在Borland C/C++ 5.02之后宣布停止此条产品U的开发,Borland C/C++的光荣历史也׃此打住,真是令h不胜感叹Q而Visual C/C++从此在C/C++开发工具市Z再也没有Ҏ(gu)。不q没有竞争的市场的确?x)让人松懈,后来的Visual C/C++q步的幅度愈来愈,MFC也数q没有什么大q步Q不像当时和Borland C/C++竞争时每一个版本都有大q的改善。看来寡占的市场的确是不好的Q这也让人回惌vVisual C/C++、Borland C/C++、Symantec C/C++、Watcom C/C++四雄逐鹿的辉煌时代了?

三、开源潮?

       Watcom C/C++产生目标E序的质量还是非常让人难忘的Q这也是不少E序员(其是游戏程序员Q青睐于q个~译器的原因Q这也促成了OpenWatcom C/C++的诞生,免费、开源,也希望很多的Z用,最新版支持C/C++/Fortran的编译?br>


q幽 2008-07-26 11:52 发表评论
]]>
如何计算滑块长度http://www.shnenglu.com/justin-shi/archive/2008/07/13/56050.htmlq幽q幽Sun, 13 Jul 2008 14:23:00 GMThttp://www.shnenglu.com/justin-shi/archive/2008/07/13/56050.htmlhttp://www.shnenglu.com/justin-shi/comments/56050.htmlhttp://www.shnenglu.com/justin-shi/archive/2008/07/13/56050.html#Feedback0http://www.shnenglu.com/justin-shi/comments/commentRss/56050.htmlhttp://www.shnenglu.com/justin-shi/services/trackbacks/56050.html

q幽 2008-07-13 22:23 发表评论
]]>
常用的工具函?/title><link>http://www.shnenglu.com/justin-shi/archive/2008/06/23/54325.html</link><dc:creator>q幽</dc:creator><author>q幽</author><pubDate>Sun, 22 Jun 2008 19:59:00 GMT</pubDate><guid>http://www.shnenglu.com/justin-shi/archive/2008/06/23/54325.html</guid><wfw:comment>http://www.shnenglu.com/justin-shi/comments/54325.html</wfw:comment><comments>http://www.shnenglu.com/justin-shi/archive/2008/06/23/54325.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/justin-shi/comments/commentRss/54325.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/justin-shi/services/trackbacks/54325.html</trackback:ping><description><![CDATA[<div id="xjtzh3r" class=cnt id=blog_text> <p>1 Cstring转成TCHAR*</p> <p>StrToTchar(CString temString,TCHAR * pTchar)<br>{<br>int tmpLength=0 ;<br>tmpLength = temString.GetLength();<br>TCHAR * ptemTchar = temString.GetBuffer(tmpLength);<br>wcscpy( pTchar,ptemTchar);<br>}</p> <p>Q 获取pȝ旉</p> <p>CString GetSysTime()<br>{//得到pȝ旉<br>CString strTime;<br>SYSTEMTIME st;<br>::GetLocalTime(&st);<br>TCHAR datetime[20];<br>TCHAR times[20];<br>GetDateFormat(LOCALE_USER_DEFAULT,NULL,&st,_T("yyyy-MM-dd"),datetime,20);<br>GetTimeFormat(LOCALE_USER_DEFAULT,NULL,&st,_T("HH:mm:ss"),times,20);<br>strTime = (CString)datetime + _T(" ")+(CString)times;<br>return strTime;<br>}</p> <p> </p> <p>CTime t = CTime::GetCurrentTime();<br>SelfInfo[8] = IntToStr(t.GetYear());<br>SelfInfo[9] = IntToStr(t.GetMonth());<br>SelfInfo[10] = IntToStr(t.GetDay());</p> <p> </p> <p>Q 写日?/p> <p><br>void Writelog(char *str)<br>{<br>FILE *fp;<br>fp = fopen("\\Storage\\LogFile.txt","w+");<br>if(!fp)<br>{<br>   return;<br>}<br>fprintf(fp,"%s\n",str);<br>fclose(fp);<br>return;<br>}<br><br><br></p> </div> <img src ="http://www.shnenglu.com/justin-shi/aggbug/54325.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/justin-shi/" target="_blank">q幽</a> 2008-06-23 03:59 <a href="http://www.shnenglu.com/justin-shi/archive/2008/06/23/54325.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【{】C++ intQcharQstringQCStringcd转换Q整理ȝQ?/title><link>http://www.shnenglu.com/justin-shi/archive/2008/06/14/53195.html</link><dc:creator>q幽</dc:creator><author>q幽</author><pubDate>Fri, 13 Jun 2008 21:11:00 GMT</pubDate><guid>http://www.shnenglu.com/justin-shi/archive/2008/06/14/53195.html</guid><wfw:comment>http://www.shnenglu.com/justin-shi/comments/53195.html</wfw:comment><comments>http://www.shnenglu.com/justin-shi/archive/2008/06/14/53195.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/justin-shi/comments/commentRss/53195.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/justin-shi/services/trackbacks/53195.html</trackback:ping><description><![CDATA[<div> <p>#include <string> <wbr></wbr>//使用C++标准库的stringcL</p> <p>using namespace std; <wbr></wbr>//同上</p> <p>#include <sstream> <wbr></wbr><wbr></wbr></p> <p>#include <iostream></p> <p>#include <stdlib.h> <wbr></wbr><wbr></wbr><wbr></wbr>//要将stringcdintcd直接转换最好有q些包含Q?/p> <p><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr>//因ؓ(f)自己写一个{换函数比较方便,函数定义参考如?/p> <p>string getstring ( const int n )</p> <p>{</p> <p><wbr></wbr><wbr></wbr><wbr></wbr><font face=宋体>std::stringstream newstr;<br><wbr></wbr><wbr></wbr><wbr></wbr>newstr<<n;<br><wbr></wbr><wbr></wbr><wbr></wbr>return newstr.str();</font></p> <p>}</p> <p><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr><wbr></wbr></p> <p>string ?CString<br>CString.format(”%s”, string.c_str());</p> <p>char ?CString<br>CString.format(”%s”, char*);</p> <p>char ?string<br>string s(char *);</p> <p>string ?char *<br>char *p = string.c_str();</p> <p>CString ?string<br>string s(CString.GetBuffer());</p> <p>1Qstring -> CString<br>CString.format(”%s”, string.c_str());<br>用c_str()实比data()要好.<br>2Qchar -> string<br>string s(char *);<br>只能初始化,在不是初始化的地Ҏ(gu)好还是用assign().<br>3,CString -> string<br>string s(CString.GetBuffer());<br>GetBuffer()后一定要ReleaseBuffer(),否则没有释攄冲区所占的I间.</p> <p>《C++标准函数库》中说的<br>有三个函数可以将字符串的内容转换为字W数l和C—string<br>1.data(),q回没有”\0“的字W串数组<br>2,c_str()Q返回有”\0“的字W串数组<br>3Qcopy()</p> <p>————————————————————?/p> <p>CString与int、char*、char[100]之间的{? -</p> <p>CString与int、char*、char[100]之间的{? -</p> <p>CString互{int</p> <p>字W{换ؓ(f)整数Q可以用atoi、_atoi64或atol?br>而将数字转换为CString变量Q可以用CString的Format函数。如<br>CString s;<br>int i = 64;<br>s.Format(”%d”, i)<br>Format函数的功能很强,值得你研I一下?/p> <p>void CStrDlg::OnButton1()<br>{<br>// TODO: Add your control notification handler code here<br>CString<br>ss=”1212.12″;<br>int temp=atoi(ss);<br>CString aa;<br>aa.Format(”%d”,temp);<br>AfxMessageBox(”var is ” + aa);<br>}</p> <p>sart.Format(”%s”,buf);</p> <p>CString互{char*</p> <p>///char * TO cstring<br>CString strtest;<br>char * charpoint;<br>charpoint=”give string a value”;<br>strtest=charpoint;</p> <p>///cstring TO char *<br>charpoint=strtest.GetBuffer(strtest.GetLength());</p> <p>标准C里没有string,char *==char []==string</p> <p>可以用CString.Format(”%s”,char *)q个Ҏ(gu)来将char *转成CString。要把CString转成char *Q用操作W(LPCSTRQCString可以了?/p> <p>CString转换 char[100]</p> <p>char a[100];<br>CString str(”aaaaaa”);<br>strncpy(a,(LPCTSTR)str,sizeof(a));</p> </div> <br> <img src ="http://www.shnenglu.com/justin-shi/aggbug/53195.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/justin-shi/" target="_blank">q幽</a> 2008-06-14 05:11 <a href="http://www.shnenglu.com/justin-shi/archive/2008/06/14/53195.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>软g工程师笔试题QC/C++Q?/title><link>http://www.shnenglu.com/justin-shi/archive/2008/06/11/52825.html</link><dc:creator>q幽</dc:creator><author>q幽</author><pubDate>Tue, 10 Jun 2008 18:46:00 GMT</pubDate><guid>http://www.shnenglu.com/justin-shi/archive/2008/06/11/52825.html</guid><wfw:comment>http://www.shnenglu.com/justin-shi/comments/52825.html</wfw:comment><comments>http://www.shnenglu.com/justin-shi/archive/2008/06/11/52825.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/justin-shi/comments/commentRss/52825.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/justin-shi/services/trackbacks/52825.html</trackback:ping><description><![CDATA[<p> </p> <strong>预处理器QPreprocessorQ?br></strong>1. 用预处理指o#define 声明一个常敎ͼ用以表明1q中有多秒Q忽略闰q问题)<br><br>#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL <br>我在q想看到几g事情Q?<br>1). #define 语法的基本知识(例如Q不能以分号l束Q括L(fng)使用Q等{) <br>2). 懂得预处理器ؓ(f)你计常数表辑ּ的|因此Q直接写Z是如何计一q中有多秒而不是计出实际的|是更清晰而没有代L(fng)?<br>3). 意识到这个表辑ּ一?6位机的整型数溢出-因此要用到长整型W号L,告诉~译器这个常数是的长整型数?<br>4). 如果你在你的表达式中用到ULQ表C无W号长整型)Q那么你有了一个好的v炏V记住,W一印象很重要?br><br><br>2. 写一?#8220;标准”宏MINQ这个宏输入两个参数q返回较?yu)的一个?br><br><br>#define MIN(A,B) ((A) <= (B) (A) : (B)) <br>q个试是ؓ(f)下面的目的而设的:(x) <br>1). 标识#define在宏中应用的基本知识。这是很重要的,因ؓ(f)直到嵌入(inline)操作W变为标准C的一部分Q宏是方便生嵌入代码的唯一Ҏ(gu)Q对于嵌入式pȝ来说Qؓ(f)了能辑ֈ要求的性能Q嵌入代码经常是必须的方法?<br>2). 三重条g操作W的知识。这个操作符存在C语言中的原因是它使得~译器能产生比if-then-else更优化的代码Q了解这个用法是很重要的?<br>3). 懂得在宏中小心地把参数用括号括v?<br>4). 我也用这个问题开始讨论宏的副作用Q例如:(x)当你写下面的代码时会(x)发生什么事Q?<br>least = MIN(*p++, b);<br><br><br>3. 预处理器标识#error的目的是什么?<br><br>如果你不知道{案Q请看参考文?。这问题对区分一个正常的伙计和一个书呆子是很有用的。只有书呆子才会(x)读C语言课本的附录去扑և象这U?<br>问题的答案。当然如果你不是在找一个书呆子Q那么应试者最好希望自׃要知道答案?br><br><br><strong>d@环(Infinite loopsQ?/strong><br><br><br>4. 嵌入式系l中l常要用到无限@环,你怎么L(fng)C~写d@环呢Q?br><br>q个问题用几个解x案。我首选的Ҏ(gu)是:(x) <br>while(1) { } <br>一些程序员更喜Ƣ如下方案:(x) <br>for(;;) { } <br>q个实现方式让我为难Q因个语法没有确切表辑ֈ底怎么回事。如果一个应试者给个作为方案,我将用这个作Z个机?x)去探究他们q样做的 <br>基本原理。如果他们的基本{案是:(x)“我被教着q样做,但从没有惛_qؓ(f)什么?#8221;q会(x)l我留下一个坏印象?<br>W三个方案是?goto <br>Loop: <br>... <br>goto Loop; <br>应试者如l出上面的方案,q说明或者他是一个汇~语aE序员(q也许是好事Q或者他是一个想q入新领域的BASIC/FORTRANE序员?br><br><strong>数据声明QData declarationsQ?/strong> <br><br>5. 用变量al出下面的定?br>a) 一个整型数QAn integerQ?<br>b) 一个指向整型数的指针(A pointer to an integerQ?<br>c) 一个指向指针的的指针,它指向的指针是指向一个整型数QA pointer to a pointer to an integerQ?<br>d) 一个有10个整型数的数l(An array of 10 integersQ?<br>e) 一个有10个指针的数组Q该指针是指向一个整型数的(An array of 10 pointers to integersQ?<br>f) 一个指向有10个整型数数组的指针(A pointer to an array of 10 integersQ?<br>g) 一个指向函数的指针Q该函数有一个整型参数ƈq回一个整型数QA pointer to a function that takes an integer as an argument and returns an integerQ?<br>h) 一个有10个指针的数组Q该指针指向一个函敎ͼ该函数有一个整型参数ƈq回一个整型数Q?An array of ten pointers to functions that take an integer argument and return an integer Q?br><br>{案是:(x) <br>a) int a; // An integer <br>b) int *a; // A pointer to an integer <br>c) int **a; // A pointer to a pointer to an integer <br>d) int a[10]; // An array of 10 integers <br>e) int *a[10]; // An array of 10 pointers to integers <br>f) int (*a)[10]; // A pointer to an array of 10 integers <br>g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer <br>h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer <br><br><br>Zl常声称q里有几个问题是那种要翻一下书才能回答的问题,我同意这U说法。当我写q篇文章ӞZ定语法的正性,我的查了一下书?<br>但是当我被面试的时候,我期望被问到q个问题Q或者相q的问题Q。因为在被面试的q段旉里,我确定我知道q个问题的答案。应试者如果不知道 <br>所有的{案Q或臛_大部分答案)Q那么也没有ؓ(f)q次面试做准备,如果该面试者没有ؓ(f)q次面试做准备,那么他又能ؓ(f)什么出准备呢?<br><br><br><strong>Static</strong><br><br>6. 关键字static的作用是什么?<br><br>q个单的问题很少有h能回{完全。在C语言中,关键字static有三个明昄作用Q?<br>1). 在函CQ一个被声明为静态的变量在这一函数被调用过E中l持其g变?<br>2). 在模块内Q但在函C外)Q一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量?<br>3). 在模块内Q一个被声明为静态的函数只可被这一模块内的其它函数调用。那是Q这个函数被限制在声明它的模块的本地范围内用?<br>大多数应试者能正确回答W一部分Q一部分能正回{第二部分,同是很少的h能懂得第三部分。这是一个应试者的严重的缺点,因ؓ(f)他显然不懂得本地化数据和代码范围的好处和重要性?br><br><br><strong>Const </strong><br><br>7Q关键字const是什么含意?<br>我只要一听到被面试者说Q?#8220;const意味着常数”Q我q道我正在和一个业余者打交道。去qDan Saks已经在他的文章里完全概括了const的所有用法,因此ESP(译者:(x)Embedded Systems Programming)的每一位读者应该非常熟(zhn)const能做什么和不能做什?如果你从没有d那篇文章Q只要能说出const意味着“只读”可以了。尽这个答案不是完全的{案Q但我接受它作ؓ(f)一个正的{案。(如果你想知道更详l的{案Q仔l读一下Saks的文章吧。)如果应试者能正确回答q个问题Q我问他一个附加的问题Q下面的声明都是什么意思?<br><br>const int a; <br>int const a; <br>const int *a; <br>int * const a; <br>int const * a const;<br><br>前两个的作用是一Pa是一个常整型数。第三个意味着a是一个指向常整型数的指针Q也是Q整型数是不可修改的Q但指针可以Q。第四个意思a是一个指向整型数的常指针Q也是_(d)指针指向的整型数是可以修改的Q但指针是不可修改的Q。最后一个意味着a是一个指向常整型数的常指针(也就是说Q指针指向的整型数是不可修改的,同时指针也是不可修改的)。如果应试者能正确回答q些问题Q那么他q我留下了一个好印象。顺带提一句,也许你可能会(x)问,即不用关键字constQ也q是能很Ҏ(gu)写出功能正确的程序,那么我ؓ(f)什么还要如此看重关键字const呢?我也如下的几下理由:(x) <br>1). 关键字const的作用是为给M代码的h传达非常有用的信息,实际上,声明一个参Cؓ(f)帔R是ؓ(f)了告诉了用户q个参数的应用目的。如果你曾花很多旉清理其它人留下的垃圾Q你׃(x)很快学会(x)感谢q点多余的信息。(当然Q懂得用const的程序员很少?x)留下的垃圾让别人来清理的。) <br>2). 通过l优化器一些附加的信息Q用关键字const也许能生更紧凑的代码?<br>3). 合理C用关键字const可以使编译器很自然地保护那些不希望被改变的参敎ͼ防止其被无意的代码修攏V简而言之,q样可以减少bug的出现?br><br><strong>Volatile </strong><br><br>8. 关键字volatile有什么含?q给Z个不同的例子?br><br>一个定义ؓ(f)volatile的变量是说这变量可能?x)被意想不到地改变,q样Q编译器׃?x)去假设q个变量的g。精地说就是,优化器在用到q个变量时必Lơ都心地重新读取这个变量的|而不是用保存在寄存器里的备份。下面是volatile变量的几个例子:(x) <br>1). q行讑֤的硬件寄存器Q如Q状态寄存器Q?<br>2). 一个中断服务子E序中会(x)讉K到的非自动变?Non-automatic variables) <br>3). 多线E应用中被几个Q务共享的变量 <br>回答不出q个问题的h是不?x)被雇䄦的。我认ؓ(f)q是区分CE序员和嵌入式系l程序员的最基本的问题。嵌入式pȝE序员经常同g、中断、RTOS{等打交道,所用这些都要求volatile变量。不懂得volatile内容会(x)带来N?<br>假设被面试者正地回答了这是问题(嗯,怀疑这否会(x)是这PQ我稍微深I一下,看一下这家伙是不是直正懂得volatile完全的重要性?<br>1). 一个参数既可以是constq可以是volatile吗?解释Z么?<br>2). 一个指针可以是volatile 吗?解释Z么?<br>3). 下面的函数有什么错误:(x) <br>int square(volatile int *ptr) <br>{ <br>return *ptr * *ptr; <br>} <br>下面是答案:(x) <br>1). 是的。一个例子是只读的状态寄存器。它是volatile因ؓ(f)它可能被意想不到地改变。它是const因ؓ(f)E序不应该试囑֎修改它?<br>2). 是的。尽这q不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时?<br>3). q段代码的有个恶作剧。这D代码的目的是用来返指针*ptr指向值的qxQ但是,׃*ptr指向一个volatile型参敎ͼ~译器将产生cM下面的代码:(x) <br>int square(volatile int *ptr) <br>{ <br>int a,b; <br>a = *ptr; <br>b = *ptr; <br>return a * b; <br>} <br>׃*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,q段代码可能q不是你所期望的^方|正确的代码如下:(x) <br>long square(volatile int *ptr) <br>{ <br>int a; <br>a = *ptr; <br>return a * a; <br>}<br><br><strong>位操作(Bit manipulationQ?/strong><br><br>9. 嵌入式系lL要用户对变量或寄存器q行位操作。给定一个整型变量aQ写两段代码Q第一个设|a(chn)的bit 3Q第二个清除a 的bit 3。在以上两个操作中,要保持其它位不变?br><br>对这个问题有三种基本的反?<br>1). 不知道如何下手。该被面者从没做qQ何嵌入式pȝ的工作?<br>2). 用bit fields。Bit fields是被扔到C语言死角的东西,它保证你的代码在不同~译器之间是不可UL的,同时也保证了的你的代码是不可重用的。我最q不q看到Infineon为其较复杂的通信芯片写的驱动E序Q它用到了bit fields因此完全Ҏ(gu)无用Q因为我的编译器用其它的方式来实现bit fields的。从道dԌ(x)永远不要让一个非嵌入式的家伙_实际硬件的辏V?<br>3). ?#defines ?bit masks 操作。这是一个有极高可移植性的Ҏ(gu)Q是应该被用到的Ҏ(gu)。最佳的解决Ҏ(gu)如下Q?<br>#define BIT3 (0x1<<3) <br>static int a; <br>void set_bit3(void) <br>{ <br>a |= BIT3; <br>} <br>void clear_bit3(void) <br>{ <br>a &= ~BIT3; <br>} <br>一些h喜欢|和清除D定义一个掩码同时定义一些说明常敎ͼq也是可以接受的。我希望看到几个要点Q说明常数、|=?amp;=~操作?br><br><strong>讉K固定的内存位|(Accessing fixed memory locationsQ?/strong> <br><br>10. 嵌入式系l经常具有要求程序员去访问某特定的内存位|的特点。在某工E中Q要求设|一l对地址?x67a9的整型变量的gؓ(f)0xaa66。编译器是一个纯_的ANSI~译器。写代码d成这一d?br><br>q一问题?gu)试你是否知道?f)了访问一l对地址把一个整型数强制转换QtypecastQؓ(f)一指针是合法的。这一问题的实现方式随着个h风格不同而不同。典型的cM代码如下Q?<br>int *ptr; <br>ptr = (int *)0x67a9; <br>*ptr = 0xaa55;<br><br>一个较晦ӆ的方法是Q?<br>*(int * const)(0x67a9) = 0xaa55;<br><br>即你的品味更接q第二种Ҏ(gu)Q但我徏议你在面试时使用W一U方案?br><br><strong>中断QInterruptsQ?</strong><br><br>11. 中断是嵌入式pȝ中重要的l成部分Q这D了很多编译开发商提供一U扩展—让标准C支持中断。具代表事实是,产生了一个新的关键字__interrupt。下面的代码׃用了__interrupt关键字去定义了一个中断服务子E序(ISR)Q请评论一下这D代码的?br><br>__interrupt double compute_area (double radius) <br>{ <br>     double area = PI * radius * radius; <br>     printf(" Area = %f", area); <br>     return area; <br>}<br><br>q个函数有太多的错误了,以至让h不知从何说v了:(x) <br>1). ISR 不能q回一个倹{如果你不懂q个Q那么你不会(x)被雇用的?<br>2). ISR 不能传递参数。如果你没有看到q一点,你被雇用的机?x)等同第一V?<br>3). 在许多的处理?~译器中QQ点一般都是不可重入的。有些处理器/~译器需要让额处的寄存器入栈Q有些处理器/~译器就是不允许在ISR中做点q算。此外,ISR应该是短而有效率的,在ISR中做点q算是不明智的?<br>4). 与第三点一脉相承,printf()l常有重入和性能上的问题。如果你丢掉了第三和W四点,我不?x)太为难你的。不用说Q如果你能得到后两点Q那么你的被雇用前景来光明了?br><br><strong>代码例子QCode examplesQ?/strong><br><br>12 . 下面的代码输出是什么,Z么?<br><br>void foo(void) <br>{ <br>     unsigned int a = 6; <br>     int b = -20; <br>     (a+b > 6) puts("> 6") : puts("<= 6"); <br>}<br><br>q个问题?gu)试你是否懂得C语言中的整数自动转换原则Q我发现有些开发者懂得极这些东ѝ不如何,q无W号整型问题的答案是输出?#8220;>6”。原因是当表辑ּ中存在有W号cd和无W号cd时所有的操作数都自动转换为无W号cd?因此-20变成了一个非常大的正整数Q所以该表达式计出的结果大?。这一点对于应当频J用到无W号数据cd的嵌入式pȝ来说是丰帔R要的。如果你{错了这个问题,你也到了得不到q䆾工作的边~?br><br>13. 评h(hun)下面的代码片断:(x)<br><br>unsigned int zero = 0; <br>unsigned int compzero = 0xFFFF; <br>/*1's complement of zero */<br><br>对于一个int型不?6位的处理器ؓ(f)_(d)上面的代码是不正的。应~写如下Q?br><br>unsigned int compzero = ~0;<br><br>q一问题真正能揭露出应试者是否懂得处理器字长的重要性。在我的l验里,好的嵌入式程序员非常准确地明白硬件的l节和它的局限,然而PC机程序往往把硬件作Z个无法避免的烦恼?<br>Cq个阶段Q应试者或者完全垂头气了或者信心满满志在必得。如果显然应试者不是很好,那么q个试在q里l束了。但如果昄应试者做得不错,那么我就扔出下面的追加问题,q些问题是比较难的,我想仅仅非常优秀的应试者能做得不错。提些问题,我希望更多看到应试者应付问题的Ҏ(gu)Q而不是答案。不如何,你就当是q个׃?#8230;<br><br><strong>动态内存分配(Dynamic memory allocationQ?/strong><br><br>14. 管不像非嵌入式计算机那么常见,嵌入式系l还是有从堆QheapQ中动态分配内存的q程的。那么嵌入式pȝ中,动态分配内存可能发生的问题是什么?<br><br>q里Q我期望应试者能提到内存片Q碎片收集的问题Q变量的持行旉{等。这个主题已l在ESP杂志中被q泛地讨了(主要?P.J. Plauger, 他的解释q远过我这里能提到的Q何解释)Q所有回q头看一下这些杂志吧Q让应试者进入一U虚假的安全感觉后,我拿么一个小节目Q下面的代码片段的输出是什么,Z么?<br><br>char *ptr; <br>if ((ptr = (char *)malloc(0)) == NULL) <br>puts("Got a null pointer"); <br>else <br>puts("Got a valid pointer"); <br><br>q是一个有的问题。最q在我的一个同事不l意?gl了函数mallocQ得C一个合法的指针之后Q我才想到这个问题。这是上面的代码,该代码的输出?#8220;Got a valid pointer”。我用这个来开始讨L(fng)一问题Q看看被面试者是否想到库例程q样做是正确。得到正的{案固然重要Q但解决问题的方法和你做军_的基本原理更重要些?br><br>Typedef <br><br>15. Typedef 在C语言中频J用以声明一个已l存在的数据cd的同义字。也可以用预处理器做cM的事。例如,思考一下下面的例子Q?br>#define dPS struct s * <br>typedef struct s * tPS; <br><br>以上两种情况的意N是要定义dPS ?tPS 作ؓ(f)一个指向结构s指针。哪U方法更好呢Q(如果有的话)Z么? <br>q是一个非常微妙的问题QQ何h{对q个问题Q正当的原因Q是应当被恭喜的。答案是Qtypedef更好。思考下面的例子Q?<br>dPS p1,p2; <br>tPS p3,p4;<br><br>W一个扩展ؓ(f) <br>struct s * p1, p2;<br><br>上面的代码定义p1Z个指向结构的指,p2Z个实际的l构Q这也许不是你想要的。第二个例子正确地定义了p3 和p4 两个指针?br><br><br>16. C语言同意一些o人震惊的l构,下面的结构是合法的吗Q如果是它做些什么? <br>int a = 5, b = 7, c; <br>c = a+++b;<br><br>q个问题做个测验的一个愉快的l尾。不你怸怿Q上面的例子是完全合乎语法的。问题是~译器如何处理它Q水q不高的~译作者实际上?x)争个问题,?gu)最处理原则Q编译器应当能处理尽可能所有合法的用法。因此,上面的代码被处理成:(x) <br>c = a++ + b; <br>因此, q段代码持行后a = 6, b = 7, c = 12?<br><br> <img src ="http://www.shnenglu.com/justin-shi/aggbug/52825.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/justin-shi/" target="_blank">q幽</a> 2008-06-11 02:46 <a href="http://www.shnenglu.com/justin-shi/archive/2008/06/11/52825.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>抨击匈牙利命名法http://www.shnenglu.com/justin-shi/archive/2008/05/02/48615.htmlq幽q幽Thu, 01 May 2008 18:26:00 GMThttp://www.shnenglu.com/justin-shi/archive/2008/05/02/48615.htmlhttp://www.shnenglu.com/justin-shi/comments/48615.htmlhttp://www.shnenglu.com/justin-shi/archive/2008/05/02/48615.html#Feedback1http://www.shnenglu.com/justin-shi/comments/commentRss/48615.htmlhttp://www.shnenglu.com/justin-shi/services/trackbacks/48615.html
匈牙利命名法是一U编E时的命名规范。命名规范是E序书写规范中最重要也是最富争议的地方Q自古乃兵家必争之地。命名规范有何用Q四个字Q名正言。用二分法,命名规范分ؓ(f)好的命名规范和坏的命名规范,也就是说名正a的命名规范和名不正a不顺的命名规范。好的舞鞋是让舞者感觉不到其存在的舞鞋,坏的舞鞋是让舞者带着镣铐赯。一个坏的命名规范具有的破坏力比一个好的命名规范具有的创造力要大得多?br>
本文要证明的是:(x)匈牙利命名法是一个坏的命名规范。本文的作用范围为静态强cd~程语言。本文的分析范本为C语言和C++语言。下文中的匈法ؓ(f)匈牙利命名法的简U?br>
一 匈牙利命名法的成?br>
匈法的表现Ş式ؓ(f)l变量名附加上类型名前缀Q例如:(x)nFoo,szFoo,pFoo,cpFoo分别表示整型变量Q字W串型变量,指针型变量和常指针型变量。可以看出,匈法变量的cd信息从单一地点Q声明变量处Q复制到了多个地点(使用变量处)Q这是冗余法。冗余法的成本之一是要l护副本的一致性。这个成本在~写和维护代码的q程中需要改变变量的cd时付出。冗余法的成本之二是占用了额外的I间。一个优U的书写者会(x)自觉地遵从一个法则:(x)代码最组l单位的长度?0个自然行以下为宜Q如果超q?0行就应该重新l织。一个变量的书写I间?x)给q一法则d不必要的隑ֺ?br>
?匈牙利命名法的收?br>
q里要证明匈牙利命名法的收益是含p的Q无法预期的?br>
范本1Qstrcpy(pstrFoo,pcstrFoo2) Vs strcpy(foo,foo2)
匈法在这里有什么收益呢Q我看不到。没有一个程序员?x)承认自׃知道strcpy函数的参数类型吧?br>
范本2Qunknown_function(nFoo) Vs unknown_function(foo)
匈法在这里有什么收益呢Q我看不到。对于一个不知道定cd的函敎ͼE序员应该去查看该函数的文档Q这是一U成本。用匈法的唯一好处是看代码的h知道q个函数要求一个整型参敎ͼq又有什么用处呢Q函数是一U接口,参数的类型仅仅是接口中的一部分。诸如函数的功能、出口信息、线E安全性、异常安全性、参数合法性等重要信息q是必须查阅文档?br>
范本3QnFoo=nBar Vs foo=bar
匈法在这里有什么收益呢Q我看不到。用匈法的唯一好处是看代码的h知道q里发生了一个整型变量的复制动作Q听h没什么问题,可以安心睡大觉了。如果他看到的是nFoo=szBarQ可能会(x)从美梦中惊醒。且慢,事情真的?x)是q样吗?我想首先被惊醒的应该是编译器。另一斚wQnFoo=nBar只是在语法上合法而已Q看代码的h真正兛_的是语义的合法性,匈法Ҏ(gu)毫无帮助。另一斚wQ一个优U的书写者会(x)自觉地遵从一个法则:(x)代码最组l单位中的(f)时变量以一两个为宜Q如果超q三个就应该重新l织。结合前q第一个法则,可以得出q样的结论:(x)易于理解的代码本w就应该是易于理解的Q这是代码的内徏高质量。好的命名规范对内徏高质量的助益相当有限Q而坏的命名规范对内徏高质量的损害比h们想象的要大?br>
?匈牙利命名法的实?br>
q里要证明匈牙利命名法在C语言是难以实施的Q在C++语言中是无法实施的。从逻辑上讲Q对匈法的收益做出否定的l论以后Q再来论证匈法的可行性,是画蛇添뀂不q有鉴于马哥曾让已杀之敌ȝ复燃Q我q是再踏上一支脚为妙?br>
前面讲过Q匈法是cdpȝ的冗余,所以实施匈法的关键是我们是否能够精地对类型系l进行复制。这取决于类型系l的复杂性?br>
先来看看C语言Q?br>
1.内置cdQint,char,float,double 复制?n,ch,f,dQ好像没有什么问题。不q谁来告诉我void应该怎么表示Q?br>2.l合cdQarray,union,enum,struct 复制?a,u,e,sQ好象比较别扭?br>q里的难点不是ؓ(f)ȝ型取名,而是为副cd取名。an表示整型数组Qsfoo,sbar表示l构fooQ结构barQausfoo表示联合l构foo数组Q篏不篏啊?br>3.Ҏ(gu)cdQpointer。pointer在理Z应该是组合类型,但是在C语言中可以认为是内置cdQ因为C语言q没有非怸格地区分不同的指针类型。下面开始表演:(x)pausfoo表示联合l构foo数组指针Qppp表示指针的指针的指针Q?br>
噩梦q没有结束,再来看看cdpȝ更阿Z富的C++语言Q?br>
1.classQ如果说C语言中的structq可以用stru搪塞q去的话Q不要梦想用cls来搪塞C++中的class。严格地ԌclassҎ(gu)ƈ不是一个类型,而是创造类型的工具Q在C++中,语言内置cd的数量和class创造的用户自定义类型的数量相比完全可以忽略不计。stdvectorFoo表示标准库向量类型变量FooQ疯狂的念头?br>2.命名I间QboostfilesystemiteratorFooQ表CboostI间filesystem子空间遍历目录类型变量FooQ程序员要崩溃了?br>3.模板Q你记得std::map<std::string,std::string>cd的确切名字吗Q我是记不得了,好像过255个字W,q是饶了我吧?br>4.模板参数Qtemplate <class T, class BinaryPredicate>const T& max(const T& a, const T& b, BinaryPredicate comp) 聪明的你Q请用匈法ؓ(f)T命名。上帝在发笑?br>5.cd修饰Qstatic,extern,mutable,register,volatile,const,short,long,unsigned 噩梦加上修饰是什么?q是噩梦?

q幽 2008-05-02 02:26 发表评论
]]>
q个I间先留着Q等大二能上|了再写Q?/title><link>http://www.shnenglu.com/justin-shi/archive/2008/02/05/42544.html</link><dc:creator>q幽</dc:creator><author>q幽</author><pubDate>Tue, 05 Feb 2008 12:26:00 GMT</pubDate><guid>http://www.shnenglu.com/justin-shi/archive/2008/02/05/42544.html</guid><wfw:comment>http://www.shnenglu.com/justin-shi/comments/42544.html</wfw:comment><comments>http://www.shnenglu.com/justin-shi/archive/2008/02/05/42544.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/justin-shi/comments/commentRss/42544.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/justin-shi/services/trackbacks/42544.html</trackback:ping><description><![CDATA[q个I间先留着Q等大二能上|了再写Q?br>q个I间先留着Q等大二能上|了再写Q?br><img src="http://www.shnenglu.com/images/cppblog_com/justin-shi/1_135440G2.gif" border=0> <img src ="http://www.shnenglu.com/justin-shi/aggbug/42544.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/justin-shi/" target="_blank">q幽</a> 2008-02-05 20:26 <a href="http://www.shnenglu.com/justin-shi/archive/2008/02/05/42544.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.shnenglu.com/" title="精品视频久久久久">精品视频久久久久</a> <div class="friend-links"> </div> </div> </footer> <a href="http://www.airesou.cn" target="_blank">þþþþaŷa</a>| <a href="http://www.7dapei.cn" target="_blank">þ99Ʒŷ</a>| <a href="http://www.vdzy.cn" target="_blank">ƷƷþþþ </a>| <a href="http://www.wannengsou.cn" target="_blank">þþƷа</a>| <a href="http://www.help0.cn" target="_blank">þùƷ99</a>| <a href="http://www.lshwn.cn" target="_blank">þ99Ʒþþþþ</a>| <a href="http://www.baidu12.cn" target="_blank">Ʒþþþþþþ</a>| <a href="http://www.oysport.cn" target="_blank">þ99׾Ʒ</a>| <a href="http://www.bb657.cn" target="_blank">þˬˬˬav</a>| <a href="http://www.2nder.cn" target="_blank">þþƷҹҹҹҹҹþ</a>| <a href="http://www.wasang.cn" target="_blank">ۺϾþһ</a>| <a href="http://www.inqh.cn" target="_blank">޹˾þþƷӰ</a>| <a href="http://www.ycjtjedu.cn" target="_blank">þwww˳_Ƭ</a>| <a href="http://www.aa110.cn" target="_blank">˾þþùۿëƬ</a>| <a href="http://www.goomba.cn" target="_blank">97Ʒ˾þô߽</a>| <a href="http://www.floodlighting.cn" target="_blank">þõӰһ</a>| <a href="http://www.f938.cn" target="_blank">þҹɫƷվ</a>| <a href="http://www.itmr.com.cn" target="_blank">ҹƷþþþþ</a>| <a href="http://www.pz25555.cn" target="_blank">2021˾Ʒþ</a>| <a href="http://www.meiguohongfeng.com.cn" target="_blank">޹þþþƷС˵</a>| <a href="http://www.vf369.cn" target="_blank">þĻƵ</a>| <a href="http://www.chaonengtiyu.cn" target="_blank">ۺϾþþþ</a>| <a href="http://www.8xbu.cn" target="_blank">޾Ʒһþ</a>| <a href="http://www.shxwy.cn" target="_blank">þþƷ7777</a>| <a href="http://www.lttao.cn" target="_blank">þþƷƷ</a>| <a href="http://www.citysoso.cn" target="_blank">97þۺɫdžѿ</a>| <a href="http://www.whbgjj1.cn" target="_blank">þ</a>| <a href="http://www.caregps.cn" target="_blank">ܻƺ۵վþmimiɫ</a>| <a href="http://www.baomintv.cn" target="_blank">ݺݾþŷר</a>| <a href="http://www.teng9si.cn" target="_blank">ˮϵþþƷ</a>| <a href="http://www.086144.cn" target="_blank">޾ƷŮþ777777</a>| <a href="http://www.sspfn.cn" target="_blank">þˬˬƬAV </a>| <a href="http://www.shecb2b.com.cn" target="_blank">þþþþþþþþѾƷ</a>| <a href="http://www.yslianzheng.cn" target="_blank">˾þˬ</a>| <a href="http://www.shlinfeng.com.cn" target="_blank">˾þۺ</a>| <a href="http://www.tvue.cn" target="_blank">þҹ³˿Ƭϼ </a>| <a href="http://www.createclouds.cn" target="_blank">ɫۺϾþĻۺ</a>| <a href="http://www.maituogangwan.cn" target="_blank">ƷѾþþþӰԺ</a>| <a href="http://www.dangong02.cn" target="_blank">þþž޾Ʒ</a>| <a href="http://www.nsimple.cn" target="_blank">ɫۺϾþ۾Ʒ</a>| <a href="http://www.sywanfu.cn" target="_blank">ԻԻ˿þþ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>