|
Linux之父炮轰C++(www.cppentry.com):糟糕程序员的垃圾语言
|
| Linux之父话糙理不糙 |
不得不看的两次从C++(www.cppentry.com)回归C的高手评论C++(www.cppentry.com) |
C语言是否该扔进垃圾桶 |
| 为什么每个程序员都应该学习C语言? |
每个程序员都应该学习C语言?我可不这么认为 |
C语言已经死了,5个需要忘却它的理由 |
|
|
| C++(www.cppentry.com)0x:崭新的C++(www.cppentry.com),还是另一个Java? |
| 编程(www.cppentry.com)语言的三大定理 |
动态语言为何难堪重任 |
动态语言面面观 |
【51CTO.com综合消息】问题
为什么使用C++(www.cppentry.com)?在你皱眉准备关掉这个网页之前,试着回答这样一个简单的问题。
答案是效率,是吗?每个人都知道答案。但是,我们应该以更专业的角度来讨论一种编程(www.cppentry.com)语言或是与之相关的事情。那么,让我再问你一个问题:效率是否是人们选择使用C++(www.cppentry.com)的唯一理由,为什么他们不用C呢?C的效率公认比C++(www.cppentry.com)高(当然,我知道,现已证明在某种程度上说,C并不比C++(www.cppentry.com)高效,但请不要在此挑错,因为即使他们是等效的,问题仍然存在)。
神话
我知道你可能会说,这是一种“择优选择”,因为毕竟C++(www.cppentry.com)就是设计成了C的优化,是C的扩充,可能它没有想象中的那么高效,但同时它却有很多梦幻的高水平的特征。那么问题就归结为“开发者真的需要这些梦幻特征吗?”我的意思是,毕竟我们都听说过KISS(Keep It Simple,Stupid!保持简单)和stuff(材料),我们也都听过这种说法——与C++(www.cppentry.com)相比,C更KISS,所以我们应该选择C。这样无休止的争论使得C和C++(www.cppentry.com)之间的比较变成了一个神话(或者是一片混乱)。令人惊讶的是,似乎很多人倾向于C,而理由是C++(www.cppentry.com)太难正确使用了。甚至是Linus也这么想。
这种现象产生的真正严重的影响是,驱使更多的人在C与C++(www.cppentry.com)之间权衡利弊的时候,他们选择了C;一旦他们开始使用C,他们很快就会感到满足和舒服,就是所说的“令人满意”的体验。这样,当争论产生的时候,他们就会站出来说与C++(www.cppentry.com)相比,C是更好的选择。而实际上,他们都没有真正试着使用过C++(www.cppentry.com),或者他们根本不是足够好的C++(www.cppentry.com)程序员。而真实的答案,往往开始与“它取决于”。
那么,我说过“它取决于”,取决于什么?显然,在一些领域选择C比C++(www.cppentry.com)更好。例如,设备驱动程序的开发通常就不需要OOP/GP(面向对象程序设计/概念编程(www.cppentry.com))技术。它只需要简单的数据操作;最重要的是,程序员能正确的知道系统如何工作,以及他们该做什么工作。再考虑OS(操作系统)的开发,我自己从来没有参与过任何OS的开发,但是读过大量OS代码(大部分是Unix),我感觉很多OS重要部分的开发也都不需要OOP/GP技术。
但是,这就意味着,在所有强调效率的领域,C都比C++(www.cppentry.com)好吗?实际上不是。
答案
让我们具体问题具体分析
首先,当人们关心效率的时候,实际上就关心两类效率——时间效率(例如:OS,运行时间,实时软件,高要求系统)和空间效率(例如:所有嵌入式系统)。但是,这种分类并不能真正帮我们决定应该选择C还是C++(www.cppentry.com),因为C和C++(www.cppentry.com)在时间和空间上都是非常高效的。真正影响我们选择哪种语言(当然是在C和C++(www.cppentry.com)之间)的是商业逻辑(这里的“商业”并不是指“企业应用商业”)。例如,是不是使用OOP/GP来表达逻辑更好,或者是不是除了考虑数据和程序还应该考虑保持软件美观。
从这点上来说,我们可以模糊地把应用分为两类(当然前提是我们只关心C/C++(www.cppentry.com),不关心java/C#/ruby/erlang等):低水平应用和高水平应用。低水平应用的意思就是,在这里并不需要那些梦幻抽象如OB(基于对象)/OOP和GP;高水平的意思当然就是需要了。显然,在所有需要C/C++(www.cppentry.com)的领域(由于它们的高效性)里,有大量“高水平”应用(参看在Bjarne Stroustrup主页上列出的),在这些领域,C++(www.cppentry.com)就会更有用。
不过,换个角度想想,即使在这些领域,程序员在他们的代码中不使用那些高水平的抽象,还是有他们应该使用C++(www.cppentry.com)的理由。为什么呢?因为你的代码不使用类和模板并不意味着不使用类库。考虑所有便捷的C++(www.cppentry.com)类库工具(即将有校准扩展tr1/tr2)的实用性,我认为在这些情况下,有非常充分的理由选择C++(www.cppentry.com)——编码的时候你可以仍然使用C的形式(以任何你想要的方式来保持KISS)。同时,你还可以使用强大的C++(www.cppentry.com)类库(例如,STL标准模板库,tr1/tr2组件等)。最终,就会发现这件可能会被很多人忽略的事情——有时KISS依靠抽象。我想,Matthew Wilson在他的新书“Extended STL,Vol1”的序言中,极其透彻地阐明了这个观点。书中提到了两段代码,分别用C和C++(www.cppentry.com)编写:
//C代码 DIR* dir = opendir("."); if(NULL != dir) { struct dirent* de; for(; NULL != (de = readdir(dir)); ) { struct stat st; if( 0 == stat(de->d_name, &st) && S_IFREG == (st.st_mode & S_IFMT)) { remove(de->d_name); } } closedir(dir); } //C++(www.cppentry.com)代码 readdir_sequence entries(".", readdir_sequence::files); std::for_each(entries.begin(), entries.end(), ::remove); And it’s even simpler in C++(www.cppentry.com)09: // C++(www.cppentry.com)09代码 std::for_each(readdir_sequence(".", readdir_sequence::files), ::remove);
|
我想,这能很清楚地说明,为什么即使人们不需要使用类和模板的时候还是应该使用C++(www.cppentry.com)——你会发现便捷的C++(www.cppentry.com)类库是多么有用。类似地,如果一个高效的容器(或者一个巧妙的指针)可以使你摆脱所有手工操作内存的麻烦工作,那么,还有什么理由要使用那些原始的malloc/free?如果一个好的string类(我不是在说std::string;人人都知道这不是C++(www.cppentry.com)做的最好的)或者regex类可以使你摆脱所有你看都不想看的混乱的字符串处理代码,那么还有什么理由要选择手动做这件事情呢?如果一个“transform”(或‘for_each’)语句可以如此简单明了地一行就完成你的工作(当然,我知道C++(www.cppentry.com)做这件事需要lambda函数的支持),那么,还有什么理由要手动写for-loops循环?如果高定制的函数真的能实现你想要的功能,那么,还有什么理由使用笨拙的工作区来完成同样的事务呢?
KISS并不意味着“粗糙”;KISS的意思是为你的工作选择最适合的工具,“最适合”意味着你所使用的工具能尽可能直接(和简洁)的帮助你表达你的想法。只要它不影响代码的可读性和易懂性。
现实问题
人们可能会说C++(www.cppentry.com)很容易会用错,而相反,C通常更容易管理和操控。一个中等水平的C++(www.cppentry.com)程序员可能会写出一大串联系紧密的类,而很快这些类就会变成一堆垃圾。但这实际上只是个别情况。一方面,在任何面向对象语言中都会经常发生这样的事情。总是有一些程序员,他们敢于在类之上再定义类,而他们甚至还不知道什么是HAS-A和IS-A;他们学习了所有定义一个类和从其他类继承一个类的语法,他们就觉得掌握了OOP的本质。另一方面,为什么问题会出现在C++(www.cppentry.com)中,是因为C++(www.cppentry.com)有很多阻止设计的复杂之处,是因为C++(www.cppentry.com)如此灵活,以至于每个用C++(www.cppentry.com)解决的问题都有很多可选的解决方案(考虑所有的GUI类库),以至于权衡选择哪种解决方案就成了艰巨的工作。C++(www.cppentry.com)的附属复杂性是一个历史遗留问题,C++(www.cppentry.com)0X做了多番努力试图摆脱这个问题;关于设计的灵活性并不是一件坏事——如果你考虑到它可以帮助好的设计师做出好的设计;如果有人谴责它,因为这样浪费了自己很多脑细胞,那这只是个人问题,而不是语言问题,或许这样的人就不应该负责做设计。如果你担心你的C++(www.cppentry.com)编程(www.cppentry.com)伙伴因为受这些高水平特征的诱惑而使得你的工程代码一团遭,那么,或许你应该建立一个编码标准并强制执行它(或者你可以遵循the collective wisdom,或者坚持C规范,或者带有C++(www.cppentry.com)类的C规范),而不是因为存在风险而退缩放弃(政策可以避免风险),因为如果不这样做,你将再也不能接触所有C++(www.cppentry.com)类库。
另一方面,存在着最重要的心理上问题——如果一个语言中存在一个稀奇古怪的性质,那么最终就会有人发现它,然后人们就会被它吸引,这就会吸引那些本来在努力做一些有用的事的人的精力(有点像墨菲法则),不要去打扰那些正在做完美解决方案的人。人们天生就会被一些稀有资源吸引。结论就是:诀窍和稀奇古怪的性质就是稀有资源,所以会引起人们的注意,更不必说掌握一种诀窍可以使人感觉自己与众不同。糟糕的是,即使是没有价值的诀窍也会引起人们的强烈注意。