`
阿尔萨斯
  • 浏览: 4170126 次
社区版块
存档分类
最新评论

驳“C语言已经死了”

 
阅读更多
<iframe align="center" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog.html" frameborder="0" width="728" scrolling="no" height="90"></iframe>

驳“C语言已经死了”

许式伟
2007-1-7

  现在,有很多C/C++程序员总是自命不凡,看不起其他开发人员。其实,或许别人更看不起他呢!
>> 有偏见的永远只是个体,而不是群体。作者加了后面那句<wbr></wbr>,无疑证明有偏见的不是C/C++程序员,而正是他自己。

  学生时代,我也曾醉心于C/C++,但时至今日,始终无法写出无懈<wbr></wbr>可击的C++代码,所以我始终认为我不会C/C++。这些年<wbr></wbr>,我一直在寻找编写C++代码的最佳模式。但是,老实说<wbr></wbr>,我还没有见到过哪个称得上高手的C++程序员,也没有见到过写得<wbr></wbr>Very good的C/C++代码。C/C++代码总是丑陋不堪<wbr></wbr>,BUG丛生!
>> 这段话更加荒谬了。没见过优秀的C/C++代码? C++标准库(STL)如此优雅。况且,有那么多经典的C/C++开源作品,以及无意之中泄漏的Windo<wbr></wbr>ws NT核心源码,哪一样不是绝世之作?我为作者浅陋感到难过。

  我用C语言编程已经超过20年了。我写过C语言的编译器<wbr></wbr>、C语言的调试器、用C开发的其他语言、游戏、客户端程序和服务器<wbr></wbr>程序,你说吧!还有什么是我没写过的。还有我的书架上充斥着折了角<wbr></wbr>的K&R和Steele的书。我太了解C语言了,但是,我讨厌他<wbr></wbr>。十分讨厌!

  当我读到一篇博客,题目是"为什么每个程序员都应该学习C语言?<wbr></wbr>"时,我真是鸡皮疙瘩满地。如果你真的是个专业的程序员的话<wbr></wbr>,你肯定觉得这是个天大的笑话,尽管作者的本意也许不是这样的<wbr></wbr>。这篇反驳的文章有点意思,但是还是没有抓住本质<wbr></wbr>。所以我展开了说一下。有以下5个原因来说明,为什么那些会C语言<wbr></wbr>,并且使用C语言的程序员,现在不但应该去用别的语言<wbr></wbr>,而且应该忘记他们学习C语言过程中的那些烦人的东西。

  1、内存分配

  仅仅关于这一点我就能写整整一篇文章了,也许能写一本书<wbr></wbr>,甚至还有可能写出能够塞满图书馆技术书籍那块,那么多的内容<wbr></wbr>。内存分配和存储单元分配的存在确确实实是个大麻烦<wbr></wbr>。你要不就是分配太少的内存不够用,要不就是分配了太多内存浪费掉<wbr></wbr>。这里的问题就是:怎么把它初始化为零呢?还是干脆就不初始化它<wbr></wbr>。但最挠头的步骤还是释放内存。所有已有的工具包都会帮助你确认<wbr></wbr>,你是否已经释放了之前分配的每一位的内存,在释放完之后是否永远<wbr></wbr>不使用它,并且会阻止你,永远不要释放它第两次。更严重的是<wbr></wbr>,分配内存和释放内存在C语言中都是很慢的,非常慢<wbr></wbr>。使用内存分配时,要考虑的各种特殊情况,我真是连想都不愿意去想<wbr></wbr>,只要问题(对象)的大小合适,我更愿意使用栈空间或者事先分配的<wbr></wbr>结构空间。如果这么做的话,我就有更值得烦恼的事了。话说回来<wbr></wbr>,发明垃圾处理器那人真应该得诺贝尔奖。
>> 内存管理是程序设计中最经典的话题。GC无疑是内存管理一个伟大的变革,但是我只是把它看作内存管理的一个解决方案,而认为不是唯一的解决方案。比GC更加优雅的方案不<wbr></wbr>见得没有。我比较倾向于在特定的情况下选择合适的内存管理方案<wbr></wbr>,而不是没有任何选择的余地,而这正是C/C++的伟大之处。 所有那些GC语言(如Java、C#等)均把这个解决方案强加给程<wbr></wbr>序员,这一定程度上来说减轻了程序员的负担,但是也同时约束了程序<wbr></wbr>员的主观能动性。"分配内存和释放内存在C语言中都是很慢的"<wbr></wbr>?不知道作者从哪里获得的结论。

  2、多线程

  我过去是喜欢C语言的,真的。直到我开始用C开发并维护多线程的服<wbr></wbr>务器。在为连接相冲突的线程保护数据方面,C语言没有为程序员提供<wbr></wbr>那怕一点点的帮助。你在使用单线程的日子里获得的每一个直觉<wbr></wbr>、经验,用在多线程的时候都是错误的。至少JAVA有表示同步的关<wbr></wbr>键字和备有证明文件(但是是个很奇怪的文件)的记忆体<wbr></wbr>,但即使是这样,除非你使用新的javax.concurrent,否则也只能在那些巨大的平行摆放的机器们面前崩溃。回到C语言上<wbr></wbr>:在模拟生产的环境下,坚持一个星期在数据中心调试一个死锁<wbr></wbr>(这事真的发生过)。而JAVA却只需要Ctrl+Break<wbr></wbr>!天哪!!!
>> C/C++语言本身确实没有太多MultiThead的支持<wbr></wbr>,这种情况在C++0x出来后可望改变。但是,请记住C/C+<wbr></wbr>+永远倾向于你使用成熟的库来解决问题。

  3、指针

  指针太难以控制了,太阴险了;我甚至没有委婉一点的方式去形容它<wbr></wbr>。我生命中每年都有几个月被用来调试那些奇怪的指针问题<wbr></wbr>。我过去常常努力获取所有的诀窍,比方说难以理解的构成符<wbr></wbr>、联合体和偏移量,以及重用最后两位做标记,还有所有其他的诀窍<wbr></wbr>。但我发现这么做根本不值得。其他语言的静态引用就可以解决了。
>> 指针是C/C++过于灵活的体现。使用指针的代码可以写得很丑陋<wbr></wbr>,但一样可以很优雅。——这一点上用何种语言不会有区别。我相信<wbr></wbr>,可以写出优雅的Java代码,那么也一定可以写出同样优雅的C/C++代码<wbr></wbr>。而反之则未必(因为有些C++某些范式是Java所不能支持的<wbr></wbr>)。C/C++语言中的选择太多,这的确是令人困惑的<wbr></wbr>,但不见得是劣势。我对C/C++程序员的建议是<wbr></wbr>,多了解和使用C++标准库,而不是过于纠缠指针相关的细节。

  4、过早的优化

  说到诀窍,你是否曾经浪费脑细胞去研究究竟*p++是不是比p<wbr></wbr>[i]快?你是否曾经花时间去试着做点变化来代替乘法<wbr></wbr>,或者去尝试使循环中的倒置运行更快的方法?还在为传递一个参数的<wbr></wbr>速度和反对添加结构,并且传递它的速度一样而苦恼不已?停吧<wbr></wbr>!算法是速度的关键,程序员的水平决定了他会使用那些算法<wbr></wbr>。知道这一点能让你的程序更好,更快一点并且让你的脑袋少扭几个筋<wbr></wbr>。好吧,有一些例子也许可以这样做的……不,你就别那么做就行了!
>> 算法优化是程序设计的关键。但是通常情况下,所有语言(包括C<wbr></wbr>/C++)的程序员研究的是关键路径的优化。研究*p+<wbr></wbr>+是不是比p[i]快?我相信这是标准库的实现者要考虑的事情<wbr></wbr>。所不同的是,C/C++程序员也可以和标准库的作者一样去考虑这<wbr></wbr>些细节,而其他语言的程序员被剥夺了这个权利。

说到优化,话题就多了。我曾经向C#的Dictionary中插入<wbr></wbr>了1亿条整数(从1万多个文本文件中读入),结果发现程序运行了整<wbr></wbr>整一个下午仍然没有完成。而我改用C++的std::map<wbr></wbr>,20分钟就搞定了。再试试对50万条自定义的结构体数据进行排序<wbr></wbr>,我相信你和我一样,会深深喜欢上C++的的高效而优雅。

  5、测试

  你最喜欢的C的单元测试的工具是哪个?嗯…一个也想不到<wbr></wbr>?单元测试一定是一点也不重要,是吧?或者是太麻烦了<wbr></wbr>,很难跟上进度,浪费时间。你可以把这个时间用到更加有用的事情上<wbr></wbr>,让它只占用工作时间的1%,那还比较合适。或者在数据中心<wbr></wbr>,通过优化的没有标记的图形来调试这个仅仅由100个同时在线使用<wbr></wbr>者引起的问题。
>> C++的测试工具,作者居然一个都想不到,我只能猜想可能他是比较<wbr></wbr>喜欢自己制造轮子的那一类。和JUnit对应的CppUnit,难道也想不到?提起CppUnit,我以前用它进行单元测试<wbr></wbr>,但从实现架构上说,我认为它继承了Java代码的臃肿<wbr></wbr>。我在WINX提供了一个Mini版本的CppUnit<wbr></wbr>,代码量大概只有几百行,功能绝不比CppUnit弱。(要了解WINX,请看这里)。

  我本来应该继续再说一些原因的,但是5个现在就足够了;说完这些<wbr></wbr>,现在感觉好点了。C以前是非常棒的…那是在1984年的时候<wbr></wbr>。直到今天,那些用C写的新代码都让我感到惊喜…如果你让我比较的<wbr></wbr>话,我觉得C++只是比C稍微好点。如果你想要学些老一点的语言<wbr></wbr>,不妨尝试Forth,List,或者APL。这些老式的语言起码能<wbr></wbr>教会你,用不同的而且优雅的方式去思考你的程序。
>> 新生的语言,必然会在吸收旧的语言上基础上进行改进<wbr></wbr>。看一个语言的生命力,并不在于看它某些地方存在的不足<wbr></wbr>。事物会发展,并趋于完善。相信C++0x出来后,C/C+<wbr></wbr>+语言又将获得新的生命力。单看Java、C#等几个新一代的语言<wbr></wbr>,其中有如此多的C++烙印,就证明了C/C++的影响是巨大的<wbr></wbr>。动不动说一门语言死了,是一种浅薄。

(来源:51cto.com 作者Ed Burnette、编译李安民)




分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics