首页 新闻 论坛 小组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 第二书店 程序员

logo

您的位置:CSDN 首页−>新闻频道−>正文

浅薄与偏见 驳“C语言已经死了”

2007.01.08  来自:天极博客      共有评论(0)条 发表评论    收藏

相信C++0x出来后, C/C++语言又将获得新的生命力。单看Java、C#等几个新一代的语言, 其中有如此多的C++烙印, 就证明了C/C++的影响是巨大的。动不动说一门语言死了, 是一种浅薄。

  《C语言已经死了,5个需要忘却的理由》

  现在, 有很多C/C++程序员总是自命不凡, 看不起其他开发人员。其实, 或许别人更看不起他呢!

  有偏见的永远只是个体, 而不是群体。作者加了后面那句, 无疑证明有偏见的不是C/C++程序员, 而正是他自己。

  学生时代, 我也曾醉心于C/C++, 但时至今日, 始终无法写出无懈可击的C++代码, 所以我始终认为我不会C/C++。这些年, 我一直在寻找编写C++代码的最佳模式。但是, 老实说, 我还没有见到过哪个称得上高手的C++程序员, 也没有见到过写得Very good的C/C++代码。C/C++代码总是丑陋不堪, BUG丛生!

  这段话更加荒谬了。没见过优秀的C/C++代码? C++标准库(STL)如此优雅。况且, 有那么多经典的C/C++开源作品, 以及无意之中泄漏的Windows NT核心源码, 哪一样不是绝世之作?我为作者浅陋感到难过。

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

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

  1、内存分配

  仅仅关于这一点我就能写整整一篇文章了, 也许能写一本书, 甚至还有可能写出能够塞满图书馆技术书籍那块, 那么多的内容。内存分配和存储单元分配的存在确确实实是个大麻烦。你要不就是分配太少的内存不够用, 要不就是分配了太多内存浪费掉。这里的问题就是:怎么把它初始化为零呢?还是干脆就不初始化它。但最挠头的步骤还是释放内存。所有已有的工具包都会帮助你确认, 你是否已经释放了之前分配的每一位的内存, 在释放完之后是否永远不使用它, 并且会阻止你, 永远不要释放它第两次。更严重的是, 分配内存和释放内存在C语言中都是很慢的, 非常慢。使用内存分配时, 要考虑的各种特殊情况, 我真是连想都不愿意去想, 只要问题(对象)的大小合适, 我更愿意使用栈空间或者事先分配的结构空间。如果这么做的话, 我就有更值得烦恼的事了。话说回来, 发明垃圾处理器那人真应该得诺贝尔奖。

  内存管理是程序设计中最经典的话题。GC无疑是内存管理一个伟大的变革, 但是我只是把它看作内存管理的一个解决方案, 而认为不是唯一的解决方案。比GC更加优雅的方案不见得没有。我比较倾向于在特定的情况下选择合适的内存管理方案, 而不是没有任何选择的余地, 而这正是C/C++的伟大之处。 所有那些GC语言(如Java、C#等)均把这个解决方案强加给程序员, 这一定程度上来说减轻了程序员的负担, 但是也同时约束了程序员的主观能动性。"分配内存和释放内存在C语言中都是很慢的"?不知道作者从哪里获得的结论。

  2、多线程

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

  C/C++语言本身确实没有太多MultiThead的支持, 这种情况在C++0x出来后可望改变。但是, 请记住C/C++永远倾向于你使用成熟的库来解决问题。

  3、指针

  指针太难以控制了, 太阴险了;我甚至没有委婉一点的方式去形容它。我生命中每年都有几个月被用来调试那些奇怪的指针问题。我过去常常努力获取所有的诀窍, 比方说难以理解的构成符、联合体和偏移量, 以及重用最后两位做标记, 还有所有其他的诀窍。但我发现这么做根本不值得。其他语言的静态引用就可以解决了。

  指针是C/C++过于灵活的体现。使用指针的代码可以写得很丑陋, 但一样可以很优雅。——这一点上用何种语言不会有区别。我相信, 可以写出优雅的Java代码, 那么也一定可以写出同样优雅的C/C++代码。而反之则未必(因为有些C++某些范式是Java所不能支持的)。C/C++语言中的选择太多, 这的确是令人困惑的, 但不见得是劣势。我对C/C++程序员的建议是, 多了解和使用C++标准库, 而不是过于纠缠指针相关的细节。

  4、过早的优化

  说到诀窍, 你是否曾经浪费脑细胞去研究究竟*p++是不是比p[i]快?你是否曾经花时间去试着做点变化来代替乘法, 或者去尝试使循环中的倒置运行更快的方法?还在为传递一个参数的速度和反对添加结构, 并且传递它的速度一样而苦恼不已?停吧!算法是速度的关键, 程序员的水平决定了他会使用那些算法。知道这一点能让你的程序更好, 更快一点并且让你的脑袋少扭几个筋。好吧, 有一些例子也许可以这样做的……不, 你就别那么做就行了!

  算法优化是程序设计的关键。但是通常情况下, 所有语言(包括C/C++)的程序员研究的是关键路径的优化。研究*p++是不是比p[i]快?我相信这是标准库的实现者要考虑的事情。所不同的是, C/C++程序员也可以和标准库的作者一样去考虑这些细节, 而其他语言的程序员被剥夺了这个权利。

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

  5、测试

  你最喜欢的C的单元测试的工具是哪个?嗯…一个也想不到?单元测试一定是一点也不重要, 是吧?或者是太麻烦了, 很难跟上进度, 浪费时间。你可以把这个时间用到更加有用的事情上, 让它只占用工作时间的1%, 那还比较合适。或者在数据中心, 通过优化的没有标记的图形来调试这个仅仅由100个同时在线使用者引起的问题。

  C++的测试工具, 作者居然一个都想不到, 我只能猜想可能他是比较喜欢自己制造轮子的那一类。和JUnit对应的CppUnit, 难道也想不到?提起CppUnit, 我以前用它进行单元测试, 但从实现架构上说, 我认为它继承了Java代码的臃肿。我在WINX中提供了一个Mini版本的CppUnit, 代码量大概只有几百行, 功能绝不比CppUnit弱。

  我本来应该继续再说一些原因的, 但是5个现在就足够了;说完这些, 现在感觉好点了。C以前是非常棒的…那是在1984年的时候。直到今天, 那些用C写的新代码都让我感到惊喜…如果你让我比较的话, 我觉得C++只是比C稍微好点。如果你想要学些老一点的语言, 不妨尝试Forth, List, 或者APL。这些老式的语言起码能教会你, 用不同的而且优雅的方式去思考你的程序。

  新生的语言, 必然会在吸收旧的语言上基础上进行改进。看一个语言的生命力, 并不在于看它某些地方存在的不足。事物会发展, 并趋于完善。相信C++0x出来后, C/C++语言又将获得新的生命力。单看Java、C#等几个新一代的语言, 其中有如此多的C++烙印, 就证明了C/C++的影响是巨大的。动不动说一门语言死了, 是一种浅薄。

发表评论 0条】

CSDN声明:此消息系转载自CSDN合作媒体,其中细节未经CSDN证实,特此声明

其他文章
相关文章
最近评论
正在载入评论列表...
热点评论

     
    网站简介广告服务网站地图帮助联系方式诚聘英才English问题报告
    北京百联美达美数码科技有限公司  版权所有  京 ICP 证 020026 号
    Copyright © 2000-2006, CSDN.NET, All Rights Reserved