Bjarne Stroustrup's FAQ_bjarne stroustrup's faq中文翻译pdf-程序员宅基地

技术标签: c++  语言  大师言论  编译器  c  编程  smalltalk  

翻译:叶丰

原网页见:http://www.c-view.org/journal/008/bs_faq.htm#IDABXKNC

这些是人们经常问我的一些问题。如果你有更好的问题,或者想对解答作一些评论,请写信告诉我<[email protected]>。请记住我毕竟不能把所有时间都花在改进我的主页上。

本文注重讨论我的一些个人观点和有关哲学的一般性问题。关于C++语言特性以及使用方面的问题,请看C++ style and technique FAQ。关于C++术语和概念,请看C++ glossary。关于C++的一些有用的资源和信息,请看C++ page。关于我写的书(包括评论和支持信息),请看book list。关于我写的论文,以及我的书的各种译本的ISBN,请看publication list

这里有叶秉哲翻译的部分FAQ(繁体中文)。

Q:

“Bjarne Stroustrup”怎么念?

A:

对于非斯堪的纳维亚人,这可能有点难。就我所知最好的建议是:“先用挪威话念几遍,然后塞一块土豆在喉咙里,然后再念:-)”这里有一个wav文件

如果你不能听这个声音文件,那这里还有些提示:我的姓和名都是两个音节:Bjar-ne Strou-strup。我名字里的B和J都不是重音,而且NE发音也很弱,所以整体听起来象Be-ar-neh或By-ar-ne。我的姓里的第一个U的发音其实应该象V,这样使第一个音节的发音在喉咙深处结束:Strov-strup。第二个U的发音有一点象OOP里的OO,但是更短一些;大概Strov-stroop的发音可以让你有一点概念。

是的,这可能是我最经常被问到的问题了:-)

P.S. 我的名字是Bjarne,不是Bjorn(这不是一个名字)、Bjørn(一个相关但不同的名字),也不是Barney(一个不相关的名字)。我的姓是Stroustrup,不是Stroustroup、Stroustrop、Strustrup、Strustrop、Strustroup、Straustrup,或者Straustroup(每一种错误的拼法都可以用google找到)。

Q:

我可以问你问题吗?

A:

当然。我会尽可能回复的。但是,请尽量避免一再询问我在主页上已经回答过的问题。而且,请不要期望得到迅速的回答。我收到的电子邮件实在太多了。

这里有一些链接:

Q:

为什么你不回复我的电子邮件?

A:

我会回信,但是我收到的信太多了。我估计我回了90%以上的信。但是有时候我会被信件淹没。有些信丢失了,有些要等到有空的时候才回,有些则要等到我回复一批相关信件的时候(经常是对我的书中潜在错误的评论)。不幸的是,越长、越有内涵的信,往往会比问题简单答案也简单的信拖得更久。

还有,如果你写信给我,请确认我能够给你回信。我很讨厌在我写完并且发出回信后,发现回信地址无效或者无法访问。

相对来说,这样两种来信被忽略的可能性比较大:关于家庭作业的问题和类似“我怎么使用某某库?”的问题。对于不回答后一个问题,我感到有点遗憾,因为提问者经常不明白DOS、Windows或者其他任何C++编程接口并不是C++标准的一部分(并且我也不可能跟上这么多的C++库的发展)。如果你没有收到回信,那么请先考虑一下你的问题是不是上面这几种类型。

Q:

为什么你不把你的网站做得更时髦一些呢?

A:

我是一个“内容提供者”,而不是网站设计者。我可以花时间来改善内容或者外观,但不能两者一起搞。

你认为很酷很时髦的东西,很可能被别人认为是极差的品味。而且,流行时刻在变。

纯文本的html下载和显示比其他任何东西都要快,毕竟还有很多人在忍受低速连接上网。

Q:

学习C++从哪本书开始最好?

A:

没有一本书对任何人来说都是最好的。不可能会有这样的书。人们有截然不同的学习方式、知识背景、学习目标以及愿意为之付出的努力。对于程序员,如果希望从经典的教科书学习新的概念和技术,我推荐The C++ Programming Language (3rd edition)。这本书讲述“纯C++”:完全独立于任何特定的开发环境以及基础库(当然,标准库除外)的语言。如果这本书你觉得不合适,那么还有其他很多优秀的C++书籍。

在我的关于“The C++ Programming Language (3rd edition)”结构、内容和定位的说明里提到:这本书面向于有一定经验,并且希望掌握C++的程序员。它不适合于正在学习第一门编程语言的初学者,也不适合于希望尽快对C++有个粗浅了解的临时程序员。因此,这本书重点在于概念和技术,并且在完整性和精确性上下了不少功夫。

如果你想知道为什么C++会变成现在这个样子,请看The Design and Evolution of C++(D&E)。理解C++的设计原则和限制能帮助你写出更好的程序。

The ACCU (The Association of C and C++ Users)网站是最好的书评网站之一,很多有经验的程序员在此仗义执言(书商们往往给出溢美之词,而象“这本书太好了,我太喜欢了,我快读完三章了,真想赶快读完它”之类的评论毫无用处。我就是搞不懂为什么会有人相信那些没有C++经验的人给出的学习建议。)ACCU网站会根据目标读者所需的经验和书籍总体质量来评定等级。

Q:

学习C++需要多少时间?

A:

这样看你所说的“学习”是什么意思了。如果你是一个Pascal程序员,你可以很容易地把基本类型、控制结构和库函数学到和你的Pascal一样水平。这需要花一天还是一星期?这取决于你采取的学习方式。我看到过各种学习速度的人。如果你是一个C程序员,你可以在一天之内学会用C++进行更有效的C风格编程。

另一方面,如果你想完全掌握C++的主要机制:数据抽象、面向对象编程、泛型编程、面向对象设计等等,而你对它们还不很熟悉,那么花上一两年不足为奇。

那么这是否就是学习C++所需的时间呢?也许是,不过要想成为更出色的设计师和程序员最起码也要这么多时间吧。如果不是为了使我们构造系统的工作方式和思维方式发生深刻变化,那么为什么要费力去学一门新的语言呢?和学钢琴或者熟练掌握一门外语相比,学一种新的、不同的编程语言和风格还算是简单的。

如果想知道更多有关C++学习的评论,请参考D&E或者我以前在comp.lang.c++发表的一篇文章

Q:

了解C是学习C++先决条件吗?

A:

不是。C和C++的公共子集比C语言更容易学:需要手工纠正的类型错误更少(C++的类型系统更严格,也更有表现力),也不需要学各种技巧(你可以用C++简洁地表示更多东西),有一个更好的库可用。作为学习C++的起点的最好子集并不是整个C语言。

Learning Standard C++ as a New Language里有一些关于如何选择C++入门学习材料(C++结构、技术和库)的讨论。有一些教材系统地采取了这种方式,例如Addison Wesley的C++ In Depth系列中Koenig&Moo写的“Accelerated C++”。

Q:

要成为一个真正的面向对象程序员,我在学C++之前需要先学Smalltalk吗?

A:

不需要。如果你想学Smalltalk,那尽管去学。Smalltalk是个很有趣的语言和系统,而且学点新东西总不是件坏事。然而,Smalltalk并不是C++,而且用C++写Smalltalk风格的代码总不是太理想。如果你想成为一个优秀的C++程序员,而且又没有几个月的多余时间,那么还是集中精力学习C++和它所包含的观念吧。

Q:

我怎么开始学习C++呢?

A:

自然,这取决于你的基础和学习动机。如果你是编程新手,我强烈推荐你去找一个有经验的程序员来帮你。否则,你学习过程中不可避免的对语言概念的误解、有关编译器实现的各种实际问题,都会大大打击你的积极性。

你需要一本好的教材,即使你的编译器有丰富的在线帮助。因为语言和库的文档及例子都不是教你概念的好老师。通常这些代码都不会告诉你为什么要这样写,以及某个技术有什么好处或者坏处。你需要把注意力放在概念和技术上,而不是语言的细节。

在选书的时候,选一本从一开始就使用标准C++和标准库的书。例如,从输入读一个字符串应该象这样:

	string s;	// Standard C++ style
	cin >> s;
而不是
	char s[MAX];	/* Standard C style */
	scanf("%s",s);
挑选那些有深厚C++功力的高手们推荐的书。不过记住没有一本书适合每个人。建议参考一下ACCU (The Association of C and C++ Users)网站上的书评

写程序要符合C++的习惯,避免只是把语法换成C++,而风格还是你以前语言的风格。如果换汤不换药,你就得不到什么收获。Learning Standard C++ as a New Language也讨论了怎么开始学习C++。

Q:

你可以教我怎么做家庭作业吗?

A:

不,对不起。我不会帮别人做家庭作业。我收到太多这样的要求,比如帮他做作业啦,帮他赶在截止时间前找到程序里的错什么的。不管怎么说,让一个专家在遥远的地方帮你改程序决不是最好的学习办法。在你身边找一个有C++经验的人来指导你吧。对于一个学生来说,良师是最好的帮助。也许正因为如此,所以良师不容易找。

同样,我也不会推荐“好的项目”给学生做。根据我的经验,要了解他或她的课程才能知道什么样的难度、什么样类型的项目才是最合适的,这非常花时间。想一个好的项目不是那么简单,而要说清楚这个项目是什么和怎么去实现它,又要写不少东西,还得花上几个小时。我没有太多的时间可以花费在这上面,这些要求几乎每周都会有。最后,一些学生似乎还认为如果项目是我推荐的,那么我从道义上就必须为他完成这个项目提供足够的帮助。

建议:去看一下TC++PL3或者其他优秀教科书里的练习题。其中很多习题都可以让你忙好几天,并且做这些习题也会鼓励有进取心的学生自己动手做一些类似的东西。或者你也可以从计算机科学以外的世界里找项目:也许一个生物学的项目无法使用一个新的测量装置,或者一个学历史的朋友不能使用改进过的数据库。很多优秀的项目以及计算机的应用都不在传统的计算机科学领域里。

去看看我的C++ style and techniques FAQ。刚开始写“读一些数据,处理它们,产生一些输出”的程序的新手也许会对一个简单的程序从输入读一个字符串的程序感兴趣。

Q:

哪里有免费的C++编译器?

A:

试试RedHat(以前是Cygnus)的CygwinDjgpp或者Borland5.5。 这些都可以在Wintel机器上运行,并且这些编译器都在努力向ISO标准靠近。

Mac用户可以到Apple去看看。

警告:如果你想把某个免费编译器用于商业用途,一定要先读一下它附带的法律条款和限制说明。

在网上或者CD里还流传着很多种古老的C++编译器。我不推荐使用旧的编译器来学习C++或者开发新的产品。因为没有必要花力气去对付早已被解决的bug,或者被标准委员会消除的限制。

要找免费的高质量的标准库(部分)实现,到SGI的STL站点STLport去看看。

关于更多的编译器信息,请看我的C++编译器列表

Q:

你是瑞典人?

A:

不,我是丹麦人。你可以去看看我的个人简历

Q:

有什么好办法可以改进我的C++程序吗?

A:

我不知道。这要看你怎么用C++。大部分人低估了抽象类和模板,而用了太多的类型转换和宏。你可以在我的文章里找到我的一些观点。抽象类和模板可以看作一种接口,它们比函数或单根继承体系(single-rooted class hierarchies)有更干净、逻辑性更强的表达能力。我的Style and techniques FAQ里有更明确的例子和观点。

Q:

选择编程语言很重要吗?

A:

是的,不过也不要希望会出现奇迹。有些人可能相信一种编程语言能够(或至少应该能够)解决他们系统构建中的大部分问题。所以他们不懈地寻找完美的编程语言,却一再失望。另一些人认为编程语言是不重要的“实现细节”,所以他们只在开发流程和设计方法上投资,而永远用Cobol、C或某些专属语言编程。一个好的语言——比如C++——可以为设计者和编程者做很多事,只要你清楚地了解并重视它的长处和限制。

Q:

ANSI/ISO标准委员会损害了C++吗?

A:

没有,他们(我们)做得很好。你可以在细节上吹毛求疵(我就是这样),但是我对ISO C++语言和新的标准库很满意。ISO C++比以前的C++版本更好,条理更清晰。和标准化工作开始时现比,你现在可以写出更精致、维护性更好的C++程序。新的标准库也是一大优点。标准库提供的list、vector、map和各种基本算法使你接触C++的方法大为改观。你可以参考The C++ Programming Language (3rd edition)里的有关标准库的章节(第三章A Tour of The Standard Library的电子版可以下载)或者我最近写的一篇文章

Q:

什么时候会有C++标准?

A:

我们已经有了!最终的技术表决是在1997年11月14日上午10:30。这里是ISO C++标准委员会发布的新闻稿。技术表决以后,C++标准在1998年以22比0的投票结果获得批准。这就是ISO/IEC 14882。

The C++ Programming Language (3rd edition)里所讲的语言和库就是以此为标准的。C++编译器和程序库的提供商已经在发售与标准草案相当接近实现了。

Q:

从哪里可以得到电子版的C++标准?

A:

C++标准(ISO/IEC 14882)可以在National Committee for Information Technology Standards的网上商店购买。在我写本文的时候,价格是US$18.00,可以用信用卡在线支付。下载的文件是PDF格式, 共有2794KB。

标准化进程后期的草案可以在这里免费下载。

我要提醒你,标准并不是一个教程,即使是专家级程序员也最好从教科书开始学习C++以及了解C++的新特性。

Q:

C++里有什么你想删掉的特性吗?

A:

不太有。问这类问题的人通常认为我会想去掉多重继承、异常、模板或者RTTI(运行时类型识别)等主要特性。如果没有他们,C++就不完整了。多年以来,我反复审查这些特性的设计,并同其他标准委员会成员一起改进一些细节问题,但去掉其中任何一个,都会对C++有重大损害。

从语言设计观点来说,我最不喜欢特性的是C++中的部分C子集。但是对于现实世界中的程序员来说,删掉这一部分特性会造成极大的麻烦。C++对于C的兼容性是一项重要的语言设计决策,而不仅是行销手段。兼容性确实很难做到和保持,但这确实使现实中的程序员得到好处,直到今天还是这样。现在C++的一些特性可以让程序员戒除使用最烦人的C特性。例如,标准库里的vector、list、map等容器以及string都可以用来避免最麻烦的低层指针操作。

Q:

C++0x会是什么样子的?

A:

我也不知道。C++0x的推出需要一个很多年的标准化过程,其间要认真考虑C++社团各种成员的需要。关于ISO C++标准的修正案(2003年版?2005年版?)的方向的讨论现在才刚开始。 目前的C++标准在很长一段时间内还会保持稳定,并且C++语言会保持更长时间的稳定,因为兼容性始终是一个重要的考虑因素。

我个人认为,几条重要的原则是:

  • 语言本身没有重大变化

  • 标准库会有重大扩充

任何改变和扩展,都是为了使C++成为一个更好的系统编程和程序库创建的平台,同时也要使C++更容易学习。当然,我们会讨论上面两个“重大”的含义。

我在SD2001w的座谈会上简要地表达了我的想法,在2002春季的ACCU会议的主题演讲中作了一些更详细的细节说明。请注意这只代表我个人关于C++发展的观点,并不是标准委员会的决策。

Q:

ARM什么时候出新版?

A:

Ellis和Stroustrup合著的The Annotated C++ Reference Manual一书,俗称“The ARM”,写于1989年,它曾是C++标准化工作的基础。 现在它已经太老了,不能反映当前的C++标准。

Andrew Koenig和我正在根据ISO标准改写这本书。因为在向ISO取得引用标准文本的许可时遇到一些麻烦,所以这项工作被延迟了。(我曾考虑引用其他文字来写,即使这样是对标准委员会的同事和朋友的不忠,或者会招致C++社团的不满。)我们的对于“ARM++”的工作被一再拖延,以至于我不敢预计它什么时候可以推出。

Q:

什么时候会出The C++ Programming Language的第四版?

A:

我想至少在2004年以前不会出。C++的定义和它所支持的基本技术在那以前不会有显著的变化。我写这本书的时候,目标就是让它能在书架上多摆一些时间,而ISO C++标准为基本的稳定性提供了保证。因此,The C++ Programming Language (3rd Edition)必须反映标准C++、标准库以及其所支持的技术,而不是某个特定的实现或者某个专有库。我会以“在线维护”的方式公布细小的改动和添加,以及新版印刷时所作的改进。请参考勘误

2000年的印刷版本(包括硬封面的“特别版”)中,我加入了两个附录:LocalesStandard-Library Exception Safety

德语译本把“特别版”称为第四版。

Q:

我应该买The C++ Programming Language的特别版吗?

A:

当然,赶快去买,多买几本。:-)

说正经的,第三版和特别版的最新印刷之间的差别只在于硬封面包装(当然还有随之而来的价格差别)。

如果我是一个没有读过The C++ Programming Language (3rd Edition)的C++程序员,我会买两本中的任意一本来读。如果我把它用作教科书和参考书,时常去翻它,那么我会选择硬封面的。第三版的封面虽然是软封面中最好的,但是毕竟比不上特别版的硬封面。

如果我已经有了一本第三版,那么当它被我翻烂了,或者版本太旧时,我就会去再买一本特别版。

同第一次印刷相比,特别版和第三版的最新印刷修正了1000个左右的错误。作为一个主要用C++工作的用户,我认为这很重要。这两个版本里还提供了两个新的附录(100页左右,可以下载:LocalesStandard-Library Exception Safety)。

现有的内容没有被移动过,所以你可以用同样的页码引用第三版的新旧印刷版本和特别版中的内容。

特别版还有一个改进过的索引。

Q:

你真的卖出X00,000本TC++PL了吗?

A:

显然是的,对于某些X的值:-) 如果你把我的书的所有翻译版本计算在内,那么数字会超过1,000,000。当然还有一些盗版的,但我不会也没办法去计算它们。

另外,我不卖书,我只是写书的。

我的书也没有任何电子版。如果你看到有的话,那一定是侵犯版权的盗版。

Q:

你推荐哪个C++编译器?库呢?

A:

我不会推荐任何编译器和库,我无法做到完全公平。但是,推荐你使用最新版本的编译器,因为通常新版本的编译器比若干年前的版本更接近ISO标准。

这里有一个不完全的C++编译器列表

尽可能选择标准的库,而不要用不标准的所谓“基础库”,尽量少用专有的扩展功能。

Q:

如果你不必考虑和C兼容,那么你设计的语言会不会就是Java?

A:

不,甚至不会接近Java。如果有人坚持要把C++与Java作比较,我建议他们读一下The Design and Evolution of C++(D&E),他们可以看到为什么C++会是现在这个样子,然后按照我对C++设立的设计标准来衡量两个语言。这些标准显然和Sun的Java小组设立的标准不同。尽管语法上很相象,C++和Java是截然不同的两个语言。在很多方面,Java更接近Smalltalk,而不是C++。

像大多数新语言一样,Java的很多相对简单性部分来源于错觉,部分来源于功能的不完备性。随着时间流逝,Java会明显变得更大更复杂,它的大小会增加二到三倍,和实现相关的扩展功能和库也会有很大增长。这是每一个商业上成功的语言的发展方式。不信你可以看看任何一个你认为取得广泛成功的语言。我没有看到过任何例外,这种现象自然是有原因的。

Java不是平台无关的,它就是平台。就象Windows,它是一个专有的商业平台。也就是说,如果你为Windows/Intel平台或者Java/JVM平台写程序,你的程序都是为属于某个单独的公司的平台而写,从而被这个公司的利益所左右。 虽然有人指出你可以用任何语言为JVM以及相关的操作系统写程序,但是JVM是强烈的偏向于Java的,它甚至还不如一般的对语言中立的VM/OS。

就个人而言,我还是坚持用具有相当可移植性的C++来完成大部分工作,而用不同的语言做其余的。

Q:

你怎么看C#?

A:

我对C#没有什么评论。你很难说服我为什么世界上需要另一个专有语言,更难说服我为什么还需要一个和特定的专有操作系统结合得那么紧的语言。

显然,我不是专有语言的爱好者,而是开放的正式的标准的爱好者。

Q:

对于大型项目,你真的更推荐Ada吗?

A:

不。我不知道这个谣言是谁放出来的,我想一定是一个过于狂热的或者存心不良的Ada信徒。

Q:

你愿意把C++与某种语言进行比较吗?

A:

对不起,我不愿这样做。你可以在The Design and Evolution of C++的介绍里找到理由:

“一些评论家要求我把C++和其他语言作比较,但我不愿意这么做。因此,我重申我一贯的看法:语言的比较很少是有意义的,也很难做到公正。主流程序设计语言之间的比较需要花大量的精力,需要有广泛的应用领域的经验,要能保持独立公正的看法,大多数人不会愿意花这么多精力。我也没有这样的时间,而且作为C++的设计者,很难让人相信我能做到完全公正。

有一种现象我很担心,这在语言比较中反复出现。虽然有些人确实想做认真的语言比较,并努力保持公正的立场,但是他们最终总是偏向于某一方面的应用,或者一种编程风格。更糟糕的是,当一个语言比其他语言更著名时,评论的观点就会产生微妙的转移:有名的语言的缺陷被认为是微不足道的,并有简单的解决办法;而其他语言里类似的缺陷就会被认为是根本上的缺点。在那些不太有名的语言里常用的解决办法往往不为作比较者所知,或者被认为不令人满意,因为这些方法不能用在他们熟悉的语言里。

类似的,那些著名语言的信息通常是最新的,而对不太有名的语言,比较者会用陈旧的信息。对于两个值得比较的语言,如果把三年前的X语言和最新的试验中的Y语言作比较,那么这既不公平也说明不了问题。所以,我对C++以外的其他语言的评论都只限于一般性评论或者针对特定的问题。”

那就是说,对于广大用户及各种应用领域,我认为C++是你的最佳选择。

Q:

别人把他们的语言和C++相比,你会不会不高兴?

A:

如果是片面的比较或者是为了商业目的,我确实会不高兴。最流行的比较往往是出自某个语言(比如叫它Z语言)的支持者,目的是证明Z语言比其他语言好。因为C++应用广泛,所以就成为Z语言的支持者想贬低的第一个语言。这些文章经常是由销售Z语言的公司发表的。令人惊讶的是,很多人会一本正经地拿这类销售Z语言的公司职员写的,没有经过专家评审的文章来证明Z语言是最好的。问题是这类比较中总会有一些事实,毕竟不会有一个语言在所有方面都优于其他语言。C++当然不完美,但这些经过选择的事实会显得很诱人,有时候完全是一种误导。

当你看到一篇关于语言比较的文章时,先看看是谁写的,再仔细考虑它是否真实公正,作者所采取比较标准本身是否考虑到对所有语言的公平性。这并不容易。

Q:

你不把C++和其他语言比较,但你为何因为C++写批评别人的文章?

A:

我不写批评别人的文章(那是对我写的一些文字的敌视性描述)。我认为作为语言的设计者,有理由(甚至是责任)来解释它的优点,并且抵御对它的恶意中伤。你可以看一下我发表的文章。我也经常指出C++的局限性以及C++设计中的一些基本假设(例如,D&E)。

Q:

对于小项目来说C比C++好,是吗?

A:

我不这么认为。我从未见过任何一个项目是优于C++的,除非是因为缺乏一个好的C++编译器。

Q:

C是C++的子集吗?

A:

从严格的数学意义来说,C不是C++的子集。有一些合法的C程序不是合法的C++程序,甚至有少数方法可以写出在C和C++中有不同含义的代码。然而,C所支持的每一项编程技术C++都支持。每一个C程序都能够以基本上相同的方法用C++写出来,并且运行时间和空间效率也差不多。把数万行ANSI C代码在几小时内转化为C风格的C++代码的事情并不少见。因此,C++是ANSI C的超集,ANSI C又是K&R C的超集,ISO C++也是1985年时的C++的超集。

写得好的C程序一般也是合法的C++程序。例如,Kernighan & Ritchie的“The C Programming Language (2nd Edition)”里的任何一个例子都是一个C++程序。

C/C++兼容性问题的一些例子:

int main()
{
	double sq2 = sqrt(2);   /* Not C++: call undeclared function */
	int s = sizeof('a');    /* silent difference: 1 in C++ sizeof(int) in C */
}
调用未定义的函数在C里是一个不好的风格,而在C++里是非法的。同样给一个声明为无参数的函数传递实参,在C和C++里也是不同的:
void f();	/* argument types not mentioned */

void g()
{
	f(2);	/* poor style C. Not C++ */
}
在C里,void*可以隐式地转换为任何指针类型,典型的自由存储的分配是用malloc()进行的,没有任何办法检查是否分配了足够的内存,例如:
void* malloc(size_t);

void f(int n)
{
	int* p = malloc(n*sizeof(char));  /* not C++. In C++, allocate using 'new' */
	char c;
	void* pv = &c;
	int* pi = pv;   /* implicit conversion of void* to int*. Not in C++ */
}
注意,把void*转换为int*还有隐藏的对齐问题。参见C++里void*和malloc()的替代品

在从C转到C++时,记住C++比C多了一些关键字:

int class = 2;    /* ok in C. Syntax error in C++ */
int virtual = 3;  /* ok in C. Syntax error in C++ */

除了上面列出了几个例子(在C++标准和The C++ Programming Language (3rd Edition)的附录B里还有更详细列表),C++是C的超集。(附录B可以下载)

Q:

C和C++的区别是什么?

A:

C++是C的一个直接后代,它几乎包含整个C作为一个子集。C++提供了比C更强的类型检查,并支持更多的编程风格。因为C++支持C语言的编程风格,同时提供更好的类型检查和更多概念上的支持,有不损失效率,所以从这个意义上来说,C++是“一个更好的C”。同样,ANSI C也是一个比K&R C更好的C。另外,C++还支持数据抽象、面向对象编程和泛型编程(见The C++ Programming Language (3rd Edition);附录B讨论了C兼容性的问题,该章可以下载。)

我从没有见过一个问题用C来表达会比C++更好(我也不相信会有这样的问题,因为每个C的构造显然都有C++的等价物。)然而,还是有一些环境C++不能很好支持,而用C会有好处。

关于C++的设计以及它与C的关系的讨论,可以看The Design and Evolution of C++

请注意上面所说的C指的是经典C和C89。C++不是C99的后代,C++和C99是兄弟。C99引入的一些特性有可能会造成C和C++的不兼容。

Q:

你真的认为C和C++应该合并为一个语言吗?

A:

如果C/C++的不兼容性被系统地完全消除,将来的演化也是有组织地以融合来防止出现新的不兼容性,那我想如果真能这样的话,对C/C++社团来说无疑是件大好事。当然能否做到是另一回事了。

我的基本观点是目前的C/C++兼容性是由于历史原因,背后并没有什么根本上的理由(尽管对于一些抱有良好愿望的高手来说,这一切“在当时看上去是个好主意”)。C/C++的不兼容对社团来说总体上没有什么好处,而对相当大一部分人来说却会引起严重的问题。这些不兼容性应该可以被消除,虽然会很难。

想了解我对C/C++兼容性问题的细节描述,可以看我写的一系列文章:

  • B. Stroustrup: C and C++: Case Studies in Compatibility. The C/C++ Users Journal. To appear September 2002.

  • B. Stroustrup: C and C++: A Case for Compatibility. The C/C++ Users Journal. To appear August 2002.

  • B. Stroustrup: C and C++: Siblings. The C/C++ Users Journal. July 2002.

  • B. Stroustrup: Sibling rivalry: C and C++. AT&T Labs - Research Technical Report. TD-54MQZY. January 2002.

我想如果不兼容性真的被消除以后(C和C++都需要作修改),还是会有C和C++两种语言,但那时C可以真正地被称为C++的一个子集

Q:

C++是什么时候发明的?

A:

我从1979年就开始设计一种新语言,它后来就成为C++。最初的版本叫“C with Classes”(带类的C)。C++的第一个版本在1979年8月开始在AT&T内部使用。同一年晚些时候,开始使用“C++”这个名字。第一个商业C++编译器在1985年10月发布,同时出版了C++ Programming Language的第一版。模板和异常处理是在80年代晚期被加入的,它们在The Annotated C++ Reference ManualThe C++ Programming Language (2rd Edition)里描述。

目前的C++是由ISO C++标准定义的,并且在The C++ Programming Language (3rd Edition)描述。

你可以在The Design and Evolution of C++找到完整的年代表和更详细的说明。

Q:

你为什么要发明C++?

A:

我想用Simula67的风格来写高效的系统程序。为此,我向C语言加入了更好的类型检查、数据抽象和面向对象编程的机制。导致这项工作的是一个关于网络分布操作系统的项目。更一般化的目标是设计一个可以写出又高效又精致的程序的语言。许多语言迫使你在两者之间作抉择。

导致我开始设计和实现C++(一开始叫“C with Classes”)的是一项有关分布式操作系统的设计任务。

你可以在The Design and Evolution of C++找到更详细的说明。

Q:

为什么AT&T要支持C++的开发?

A:

AT&T需要构建比别人更加复杂更加可靠的系统。从而,我们必须对市场施加影响,并且帮助建立符合我们需要的标准,否则我们就不会有构建我们系统所需的工具。就业界自身来说,也需要创造语言和工具来解决一般性的问题。类似的,老师们也倾向于适合学生和研究者的语言和工具,即使它们不适合某些特定的任务。

在我开发C++的时候,以及早先Ken Thompson和Dennis Ritchie开发Unix和C的时候,AT&T可能是世界上最大的民间软件用户(以及消费者)。我们使用很多种类的系统,从最小的嵌入式处理器到最大的超级计算机和数据处理系统。我们需要一个可以应用于多种技术领域和多种平台的开发系统。C和C++就是基于这样的要求来设计的。

这样的通用性是最基本的要求,专有的特性被认为会对选择平台和厂商产生限制。因此AT&T曾经是也一直会是正规标准(如ISO C和ISO C++)的主要支持者。

事实上,AT&T也靠Cfront(我最早编写的C++编译器)赚了足够的钱,开发C++的投资得到了成倍的回报。

Q:

你拥有C++吗?

A:

不。如果说有人“拥有C++”的话,那只能是ISO。AT&T把我以前写的C++手册的所有权利交给了ISO。现在ISO C++标准的版权归ISO所有。

编译器厂商不需要为C++向我或者AT&T支付版税,ISO标准本来就是让所有人免费使用的。(当然标准规格书的拷贝是需要花钱向ISO或者国家标准委员会买的。)

Q:

为什么C++没有垃圾回收机制?

A:

如果你想要自动垃圾回收,有一些不错的商业的和公共域的C++垃圾收集器可以用。在垃圾收集技术可以适用的应用程序里,C++的垃圾收集和其他支持垃圾收集的语言相比性能更好。The C++ Programming Language (3rd Edition)里有关于C++自动垃圾收集的讨论。也可以去Hans-J. Boehm的关于C/C++垃圾收集的网站看看。

而且,C++还支持其他内存管理技术,不用垃圾收集也可以安全地隐式地管理内存。

Q:

为什么C++的“Hello world”程序编译结果要比C的大10倍?

A:

在我的机器上不是这样,你的也不应该是这样。实际上,在我的机器里C++版的“Hello world”生成的目标代码要比C版本小。没有语言层面上的原因会使一个版本比另一个大。这都取决于编译器实现者如何组织程序库。如果你发现一个版本明显大很多,向编译器实现者报告这个问题吧。

Q:

象C++这样的古老语言可以和现代时髦的先进的语言竞争吗?

A:

显然,你把C++称为古老语言说明你有偏见(请看遗留代码)。把这先放一边,人们问这个问题时通常脑子里想的是JavaC#。我虽然不会把C++和那些语言作比较,但是我还是指出“时髦”不代表“更好”。Java和C#的根源都是80年代风格的OOP,这种渊源甚至比早期的C++更深。

自从1987年前后开始,C++语言的发展焦点和相关的编程风格开始转向使用模板、静态多态性、泛型编程和多范型编程。这远远超出那些被大量炒作的专有语言的范畴。另一个重要差别是C++对用户自定义类型的支持达到了和内建类型同样的程度,再结合使用模板、构造函数、析构函数,C++程序员可以运用(我认为的)更高级的编程和设计技术,这是那些经常拿来和C++作比较的语言支持不了的。

标准C++和它所支持的设计编程技术欠了函数型语言(functional language)很多情,特别是ML语言。ML早期变种的类型推导机制(以及其他很多东西)是创造C++模板的灵感的一部分来源。函数型编程(functional programming)中一些更有效的技术启发了STL和C++函数对象的使用。而另一方面,函数型编程的社团错过了面向对象编程的浪潮,他们的语言和工具很少受益于大规模业界实践的成熟经验。

显然,我也不认为编程语言里,有没有垃圾收集是判定“先进”与否的唯一决定性特征。特别是C++提供了有效而高效的内存管理技术,你不需要使用垃圾收集器也可以消除资源泄漏。如果你不同意,那也有很多不错的C++垃圾收集器可以使用。

Q:

什么是多范型编程?

A:

多范型(multiparadigm)编程是“以多种风格编程,各尽所能”的花哨讲法。例如,当需要在运行时区分对象类型时用面向对象编程,而在需要静态类型安全性,并且追求执行效率的时候使用泛型编程。显然,多范型编程的主要威力体现在使用多种范型(编程风格)的程序中,所以要通过用多种支持不同范型的语言来创建同样效果的系统是很难的。多范型编程的最引人注目的效果是:如果使来自不同范型的技术紧密协作,就可以写出比用单范型的程序更精致、维护性更好的代码。举一个简单的例子,遍历一个多态类型的静态类型容器可以这样写:

	void draw_all(vector< Shape* >& vs)	// draw each element of a standard vector
	{
		for_each(vs.begin(),vs.end(),mem_fun(&Shape::draw));
	}
这里,Shape*是定义集合类型类层次接口的抽象基类。这个例子可以很容易地推广到任何标准库里的容器:
	template< class C > void draw_all(C& cs)	// draw each element of a standard container
	{
		for_each(cs.begin(),cs.end(),mem_fun(&Shape::draw));
	}

Jim Coplien的书“Multiparadigm Design for C++”(Addison Wesley, 1998)探讨了在设计和设计方法中多种范型的运用。

Q:

你对EC++怎么看?

A:

EC++(差不多)是C++去掉异常、模板、命名空间、RTTI支持、多继承等特性后的一个子集, 由一个“工业联盟”定义。我不赞成定义子语言或者方言,特别是不支持标准库的子集,这样用户就必须各自开发不兼容的基础库。我害怕定义C++的子语言会造成用户群体分裂,并引起相互间攻击。(1999/3/31:我看到一个广告用了一个生动的图片来说明EC++是如何通过废除命名空间、模板、标准string及其他东西来“减肥”的。Sigh。)我更原意在一个开放的研讨会(如ISO或一个国家标准组织)里为“标准”工作。

我不认为对于嵌入系统来说,定义C++的子语言或者方言是必须的。(见我在Spring'99 Embedded Systems Conference上的主题演讲)嵌入系统开发社团应该得到一个专门小组的更好支持,这个小组将考虑嵌入系统开发社团的需要和C++有怎样的联系,并将其文档化。这样不同的项目和组织都会有一个合理的基础来决定使用C++的哪一部分。嵌入系统开发社团是多样的。很多人需要模板,一些人又在使用异常,而命名空间对程序的大小和速度没有影响。在未来的几十年里,只有ISO C++标准定义的语言才是足够灵活、通用、定义良好的,能满足嵌入系统开发社团的需要。相对少数的情况下,标准C++在运行时的空间和时间消耗确实会成为一个问题(通常是因为编译器不是最优的),这时可以通过编译开关来帮助优化代码(如,一些项目和一些编译器在关掉异常后,会有显著的性能提高,但也不尽然)。

Q:

C++的面向对象概念是来源于Smalltalk吗?

A:

不是。C++里的关键概念:类、派生类、虚函数(换句话说,就是封装、继承和多态的概念)来源于Simula,就象Smalltalk一样。用家族关系来比喻,C++和Smalltalk是兄弟。

Q:

C++是面向对象语言吗?

A:

C++是一种多范型编程语言,它支持面向对象以及其他有用的编程风格。如果你想找的是强制你按照某一种方式做的语言,那么C++不是你想找的。没有一种正确的方法可以写所有程序,甚至即使有这种方法,也无法强迫所有程序员都使用它。

那就是说,用C++来写C风格的程序对大多数应用来说不是C++的最佳使用方式。要成为真正的C++高手,你必须合理的使用抽象机制和类型系统,并符合它们的初衷。试图忽视或者打败C++类型系统都会让你经受严重挫折。

用C++写Smalltalk风格的程序和写C风格程序一样,也不是理想的方式,容易使人灰心。

想了解更详细的讨论,可以到我的参考文献里看关于概论和风格的文章。特别是我的OOPSLA论文“Why C++ isn't just an Object-Oriented Programming Language”。

Q:

那真是你说的吗?

A:

是的,我是说过“C容易让你开枪时不小心打到自己的脚,C++虽然不这么容易,但是你如果真这么做了,它会把你整条腿轰掉”。但人们往往或忽视,我对C++所说的话在不同程度上对于任何强大的语言都是正确的。当你防止人们犯简单的错误时,他们就会开始犯新的、不那么明显的错误。那些能避免简单错误的人,可能会直奔不那么简单的错误而去。对于坚固的保护性的环境,有一个问题,就是难题总是被太晚发现,以至于一旦发现就难以补救。并且,罕见的问题比常见问题更难发觉,因为你往往不会怀疑到它。

我也说过“在C++里面存在着一个更小一些和更清晰一些的语言,它正在挣扎着浮现出来”。比如,原文在The Design and Evolution of C++的207页(译注:中文版156页)就能找到。不过这个更小更清晰的语言不是JavaC#。原文是在名为“Beyond Files and Syntax”的小节里。那里我指的是C++的语义要比它的语法清晰得多。我是在考虑一种编程风格、程序库和编程环境,相对关注于C的低级层面的古老用法而言,它们强调更清晰更有效的编程实践。

Q:

那篇IEEE对你的采访是真的吗?

A:

是那篇坦白我故意把C++设计为一个糟糕的语言,从而写出难以维护的代码以增加程序员薪水的采访?

那当然不是真的。真正的IEEE采访在这里

Q:

什么是“遗产代码”?

A:

“遗产代码(legacy code)”通常是作为一个贬义词,用来表述以某种作者认为过时的或者与他所推销的东西竞争的语言或风格写的代码。“遗产代码”经常不象所说的那样不能工作或者无法扩展。

Q:

为什么要叫做C++?

A:

在开始的几年里,我把我的语言叫做“C with Classes”。然而人们总把它叫做“new C”,后来就简称为“C”了。这样就导致原来的C被称为“plain C”、“straight C”和“old C”。最后一个名字显得傲慢无礼,所以为了礼貌以及避免混淆,我开始寻找一个新的名字。我选择了C++,因为它比较短,也有很好的解释,并且不是“什么什么C”的形式。在C里,根据上下文,++可以被读成“next”、“successor”或者“increment”,尽管通常还是读“plus plus”。C++这个名字以及第二候补++C是产生笑话和双关语的肥沃土壤,其中很多在这个名字被确定以前就很有名,人们也很欣赏它们。C++这个名字是Rick Mascitti建议的,最早使用是在1983年12月。

至少有一打语言叫做D。D&E里有更多关于命名的琐事。

Q:

C++用户的数量现在还每年成倍增长吗?

A:

不。在1980到1991其间,C++用户数量每7个半月就会翻一倍(见The Design and Evolution of C++)。然而,显然没有足够的程序员来保持这样的增长率。从我能得到的几个数字看(编译器和书的销量、我认识的几个顾问的工作量、IDC等),我估计现在的增长率在5%到10%左右,很稳定,正增长。IDG估计在1996年一共卖出了一百二十万份C++编译器。他们2001年对C++程序员数量的估计是三百万左右,那似乎是可信的。

Q:

你有没有想到C++会如此成功?

A:

当然没有。通用目的编程语言的成功率非常地低,这我是知道的。我还知道成功的机会还受市场推销的影响,我没有那个能力。

C++最初是作为一个通用工具来设计和实现的,定位于我和我的同事面临的一些特定的问题。它的通用性以及效率后来被证明可以满足比我预期广泛得多的需要。对通用性的强调——而不是为特定问题提供特定解决方案——是C++始终保持的一个理念,也很好地为开发社团服务,即使多年以来开发社团所面临的特定问题一直在变。

Q:

你现在在忙些什么?

A:

做一个好一些的FAQ :-)

说正经的,我在寻找一些基本方式,用来改进构造大型系统时所用的工具和方法。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/elmar/article/details/225656

智能推荐

collection集合总结_集合collection下面集合类特点总结-程序员宅基地

文章浏览阅读145次。Collectionlist 有序 带索引,通过索引就能够精确查找元素,元素 可以重复增加:add(element) add(index,element):方便摘要删除:remove(element) remove(index)修改:set(index.element)查询:get(index)|-Vector 也是一个可增长的数组结构,同步的,查询速度慢,增删速度更慢|--Ar..._集合collection下面集合类特点总结

Android端图像处理方法总结_图像处理安卓-程序员宅基地

文章浏览阅读6.7k次。Android端图像处理方法在Android机中进行图像处理,常用的方式有两种: 一种是单纯使用JAVA语言进行图形处理,相当于你将C或者C++编写的图像处理方法,又重新用JAVA编写了一遍。这种开发方法需要你在opencv官网,首先下载好Opencv的Android的版本,然后将它配置到你的项目中,这样你进行图像处理时就可以直接调用一些现成的方法,比如灰度化、边缘化处理、图..._图像处理安卓

JDK 11 最新 JEP 提案:计划支持 TLS 1.3-程序员宅基地

文章浏览阅读183次。(点击上方公众号,可快速关注)转自:开源中国JDK 11 最近有什么消息?我们不妨来看一下它的进展情况,包括最新的 JEP 提案。Java 的新版本发布计划意味着总会有一..._tls1.3需要jdk

<二>Material主题的使用_material这个主题-程序员宅基地

文章浏览阅读1.2k次。http://developer.android.com/training/material/theme.htmlMaterial主题带来的效果体现在以下几个方面:System widgets that let you set their color palette(调色板)系统控件(部件)的触屏反馈动画Activity跳转动画可以在app中对color palet_material这个主题

el-upload手动控制上传多文件校验和文件删除_el-upload handleremove-程序员宅基地

文章浏览阅读1.1w次,点赞8次,收藏21次。之前写过一篇关于el-upload单文件自定义上传文章:axios+elementui的upload使用http-request自定义文件上传_Suk_阿硕的博客-程序员宅基地_http-request自定义文件上传<!-- 关于组件的部分属性: action:上传的地址,和axios没关系,elementui自己发请求 :show-file-list:是否显示上传的文件列表 :on-success:上传成功的回调 :on-error:上传失败的回调 :before-upload:上传之前的回调,可._el-upload handleremove

linuxTab键命令补全安装_linux可以把命令tab出来需要安装哪个-程序员宅基地

文章浏览阅读2.6k次。安装Tab键#安装tab命令补全[root@Mikrotik ~]# yum -y install epel-release yum-plugin-fastestmirror bash-completion#立即生效命令[root@Mikrotik ~]# source /etc/profile.d/bash_completion.sh _linux可以把命令tab出来需要安装哪个

随便推点

浙大数据结构习题笔记:04-树4 是否同一棵二叉搜索树(25 分)_04-二叉搜索树1 是否同一棵二叉搜索树 (20 分) 给定一个插入序列就可以唯一确定一-程序员宅基地

文章浏览阅读930次。04-树4 是否同一棵二叉搜索树(25 分)给定一个插入序列就可以唯一确定一棵二叉搜索树。然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到。例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结果。于是对于输入的各种插入序列,你需要判断它们是否能生成一样的二叉搜索树。输入格式:输入包含若干组测试数据。每组数据的第1行给出两个正整数N (≤10)和L,分别是每个序列插入元素的个数和需要检查的序列个数。第2行给出N个以空格分隔的正整数,作为初始插入序列。最后_04-二叉搜索树1 是否同一棵二叉搜索树 (20 分) 给定一个插入序列就可以唯一确定一

Josh 的复习总结之数字信号处理(Part 5——部分 FFT 蝶形图)_fft蝶形图-程序员宅基地

文章浏览阅读8.2k次,点赞14次,收藏82次。本文主要总结了常用的 4 点、8 点和 16 点FFT的蝶形图的画法。对于 4 点 FFT,包含了基-2 按频时间/频率抽取、分裂基-2/4 按频率抽取、基-4 按频率抽取的蝶形图的画法;对于 8 点 FFT,包含了基-2 按频时间/频率抽取、分裂基-2/4 按频率抽取的蝶形图的画法;对于 16 点 FFT,包含了基-2 按频时间/频率抽取、分裂基-2/4 按时间/频率抽取、基-4 按频率抽取的蝶形图的画法。_fft蝶形图

Cookie Domain设置错误引发的单点登录死循环问题_document.cookie设置domain不生效-程序员宅基地

文章浏览阅读1k次。问题现象在业务系统B登录之后,打开B系统的一个内嵌iframe页面page1,page1需要访问业务系统A/create接口,屏幕出现一片白色,跟踪chrome network发现请求截图如下:可以发现,浏览器在不断的访问A/create接口,然后访问passport/serviceLogin接口,然后访问A/sts接口,然后再次访问A/create,再次访问passport/serviceLogin,再次访问A/sts,陷入死循环.单点登录流程图上方流程图是梳理了单点登录代码拦截器_document.cookie设置domain不生效

原子类compareAndSet方法-程序员宅基地

文章浏览阅读755次。compareAndSet() returns true if the current value equals the expected value v, and thus the value was updated to v + 1.In your first version, if both threads get the same initial value then one will ..._compareandset 原子

session 超时的时间设置-程序员宅基地

文章浏览阅读394次。为单个Web应用 配置超时时间可以在web.xml中使用元素,如[xhtml] view plaincopy 15 ... 这个时候的“15”单位是分钟!如果在配置Servlet是指定初始化参数决定超时时间,例如下:[xhtml] view plainc..._securecart session 超时时间

JoyOI(TYVJ)1061-Mobile Service【线性dp】-程序员宅基地

文章浏览阅读535次。正题题目链接:http://www.joyoi.cn/problem/tyvj-1061题目大意有n个点,每个点之间都有权值不同的边,有3个机器人,有m个任务地点,机器人必须按顺序赶到任务地点,求最小代价。解题思路我们可以让fi,jfi,jf_{i,j}表示两个机器人在i和j,另外一个在上一个任务地点,然后动态转移就是让3个机器人任意一个去任务地点。 动态转移方程..._joyoi

推荐文章

热门文章

相关标签