学习C/C++的经验谈

    工作已经有三年半,算上学校里的时间,大约已有7年的C语言和 5年的C++使用经验;熟练使用C/C++也有3年以上;现在的我自认为是可以称得上精通C/C++,基本现在市面上广泛被推崇的经典书籍,如:《C++ Primer》、《高级C++编程技术》、《STL原码剖析》、《Effective C++》、《C编程陷阱》、《Thinking in C++》等等,这些书只有《高级C++编程技术》和《C编程陷阱》在早些时候是通篇看完的(也是因为它们都比较薄),其它的现在基本上都已经不能启发我 了,这些书虽然内容各不相同,但针对的读者水平是一样的,应该是已经学会编程语言,能够独立编程但尚未精通,在某些方面存在一定问题或欠缺的人;
    对于书籍,我现在的追求又回到了纯理论,基本上是远离编程语言和计算机,比如,小波变换和《Algorithm I-IV》;

    言归正传,关于很多人疑问的先学什么后学什么的问题,我认为:如果你选择C++作为最终的工具,或者是以C++为主的,那么我强烈建议你先学习C语言;
     首先要说明的是,C和C++是两件截然不同的东西,学习C++可以完全没有C的基础,或者说可以完全不用先学C;但是,这样你是永远也不可能成为真正的C ++大师的;你最多只能成为一个C++的熟练工人;C和C++有一个共同的奥义:内存管理,而你不学习C,单从对C++的理解是不可能掌握这项最伟大的技 术的;
    C++是面向对象的,C不是,它的特点是结构化程序设计思想,或者说是面向过程的;而C++在语法上以C的语法为基础,兼容C的语 法,这让它看上去有点凌乱;甚至C的程序不需要任何改动就可以用C++的编译器编译;对于已经掌握C语法的人,学习C++比学习其它语言(如 Delphi)要觉得容易些;而对于资深的C程序大师,那么学习C++是痛苦的,甚至完全接受不了C++,因为他们的本质是不同的;
    同 样,如果你有一定的C++基础,那么学习Java你也会觉得容易;但对于真正的C++大师,他是不会接受Java的;每一种语言都有它的精髓和奥义,虽然 C、C++、C#和Java都属于同一语言体系,但他们之间是天差地别的,只有真正进入它们的世界的高人才可以感受到这种质的区别;
    如果你本打算最终学习C#或Java,那么你完全不需要学习C或C++,不需要以C/C++为基础;
     如果你在学习C之前从未接触过编程,那么很遗憾,作为第一门程序语言,C是最难学的;C不是我的最初学习的程序语言,我的第一门程序语言是QBASE,在 高中的计算机课上,貌似是个数据库和报表的编程环境;所以,和许多大学生朋友们不一样,在我学习C之前,就知道计算机程序是怎么一回事了;
     学习计算机程序有两大难点,第一,就是要理解“程序是什么”,第二,就是要理解你所学的这门语言是什么;因为C语言的第二个问题很深奥,如果你之前又没有 接触过其他程序语言,对于计算机程序是什么的理解都还很模糊,那么你就会觉得一头雾水,而且学习计算机程序和以往你从小学到高中的任何一门课都不同,既不 是靠背也不是靠算,尤其是农村来的同学,有的连计算机都没见过,学习编程就是有力使不上的感觉,越是使大力气就越是晕;
    简单地说,编程就 是通过原子指令的组合,去达到你需要实现的目的,而达到同样的目的,选择的原子指令的种类与数量,组合的流程与方式,都是不唯一的;我认为最恰当的比喻应 该是搭积木,书本所写的只有各种积木的介绍,所以你靠背书只能背下所有积木的知识,但是却不能搭出房子来;书本的例子只是教你几种房子的搭法,你照样画 瓢,也只会搭那几种房子;编程的难点在于,你只有各种积木和要搭的房子的照片,你要想的是如何去搭,而且很明显搭的方法是不固定的;所以,光看不练等于没 学;编程的关键是在于怎么搭房子,而不是各种积木都是什么;
    所以,如果你以为看完了多少本书就是学会了一门编程语言的时候,即便书的作者多么伟大,书的内容多么精妙,你其实什么都没有学会,还是傻呆呆地站在起跑线上呢;
    学习第一门编程语言首先要解决的就是“程序是什么”的概念,“程序”的定义任何书上都有,但真正的理解只有靠自己去切身体会,当你认为明白“程序”是个什么东西的时候,才仅仅是开始入门;
     第二个问题,C语言是什么?这个答案可能每一个人都不一样;我说,C语言就是指针,C语言中一切都是指针,这就是我那么多年对它的理解;为什么说C比其它 语言难学?因为指针!有了指针,使得C更接近物理的计算机,因为其它语言没有指针这个概念,使得它们的抽象化程度更高,更接近人类的思维;想学好C语言就 必须学会以计算机的方式去思考问题,所有的C语言大师都会用人脑凭想象编译代码和调试程序;
    如果你尚停留在看int是int,看double是double的阶段,那么你才刚刚入门;只有看int不是int,看double不是double,用指向int的指针操作double的数据,当你抛弃类型这个概念的时候,你才是走上了成为一名熟练工人的道路;
     学习任何学问都是一样,都是从简单到复杂,再从复杂到简单;只有当你可以用很简单的话去归纳和总结它的时候,才是真正掌握它的时候;学习编程就是要靠个人 亲自去体验获得领悟,不是他人的语言和文字所能灌输的,而C语言的难度在于,别的语言可能你累计编写1万行代码就可以掌握,C语言可能就需要2万、3万 行,那绝对是一个倍数的差距;

    C++的奥义当然是面向对象;但是掌握C++的语法并不代表就掌握面向对象的技术,这个世界上使用 C++却不懂面向对象的人很多;C++仅仅是支持面向对象,也就是说他的语法包含面向对象的特点,但面向对象不是语言特质,而是一种思想;C不是面向对象 的语言,但用C一样能写出具有面向对象思想的程序;
    什么是面向对象?这同样是需要亲身去体会的;我认为这是比学习C语言更需要时间的琢磨的事情;
    对相当一部分人而言,C++、C#和Java都不是面向对象的语言;
    自己不写类,或几乎不写类,或很少写类,或写类也就写那么几个的,都不是面向对象的程序员;
    只知道使用别人写的类的,也不是面向对象的程序员;
    只有自己写类,写很多类,写类库,自己调用自己写的类,类之间相互调用、继承,才能算得上是具有面向对象思想的程序员;此外,还要看类的层次、接口设计是否合理,才能区分掌握面向对象的技术程度;
    C ++明显要比C#和Java难学,原因:第一,指针!C++是永远也不会放弃指针的,如果你接受不了它,那么请选择那些没有指针的语言;C和C++两大共 同的奥义就是:内存管理,和程序员是不会犯错误的;如果程序员写错了代码,那么他一定是有他这样写代码的理由,这就是C/C++的理解;因此,指针这个最 危险的东西成为了大师们最喜爱的利器,也是C/C++中最最重要的部分;所以,C++中不会出现内存回收器那种多余的东西;(因为程序员是不会犯错误的, 那么内存泄露也是有他需要泄露的理由的,如果你觉得这句话很可笑,那么你还离大师很远呢,直到你认为它真的是太正确了)
    第二,凌乱的语 法,因为它实际包含了两种语言的语法,而且部分C语言的关键字在C++中被赋于了新的含义,但又保留原来在C语言中的含义;如果你是初学者,当你不清楚编 译器什么时候做C解释,什么时候做C++解释的时候,就容易产生混淆;通常,C++的程序员学习C#和Java很快,但C#和Java的程序员学习C++ 基本就和他们刚学C#和Java那会一样,几乎没有任何可以借鉴的地方;
    C++之所以会这样,这与它的发展历史有关,C++最早的时候叫 C with Class,而早期版本的C++编译就是直接将C++代码转换为C代码再进行编译的;所以,C++现在的特性都是可以由C实现的,如果你能理解这一点,对 你学习C++是很有帮助的;或者,你可以将C++理解为,为了面向对象而偷换概念的C;

    对于具体怎么学习编程,学习的时候一本书就足够了,而且不需要多么高深的书,不需要是外国人写的,学校发的教材就可以了,虽然你最后会发现它错误百出,又不全面,但高手都是以这样的书起步,最后又把它扔掉的;对于书的态度,只要它的水平比你高就可以了;
    学习没有任何诀窍,也没有太多的经验可以传授的,听课、看书,然后编习题,最好是看一章编一章的习题,不要把整本书都看完了再去编程;打开书编书本的例子,合上书编书本的习题,习题的正确与否以你程序的效果为准,而不是正确答案或别人写的程序;
    我个人的经历,大学里没有看课本以外的编程书,没有做老师布置的以外的习题,所有习题都是自己独立完成的;所以,书上的例子和习题其实我也是没有做全的,如果你做全了,那我佩服你;起码做到和我一样,你就是全系C语言第一名!

    最后是关于书的选择,首先是针对那些从零学起,白手起家的同学,前面我列举的书都不适合你,普通的大学教材(学校里发的)就最适合你了,个人建议潭浩强(我就是用他的C语言教材的)和钱能(没看过,听说不错)的;
    对于已经学会语法,能够合上书独立编程,且累计编写的程序达到1万行的,可以看前面我列举的书,直到觉得这些书很无聊为止;
     对于接触C/C++三年以内的同学,不要看任何关于实际开发环境的书籍,如:封面上带有Microsoft Visual C++字样的书,号称多少天学会或精通C++的书(那是笑话你也信?),各种编程安例、实例,什么一百例,一千例的书(一百万例也不要去理他),看上去很 时髦的书,什么网络编程啊,什么图象、声音、多媒体啊,什么黑客啊,什么网站开发啊,以上通通都不要去看,有百害而无一利;
    其实很简单,从菜鸟到高手用不了几本书,但需要很多个键盘;
    (本文只讨论语言学习,其他的书(如数据结构和算法等)我就不提了,见谅)