“如何学好c “,在各种论坛不知道见过多少遍了,也听不少师弟师妹们过过多少遍了,但这个问题没有标准答案,我真的希望有。但我还是想把自己的想法写下来,把近十年来学习、使用c 的一些感觉写下来与朋友们分享,也希望对一些初学者有用,一家之言尔。
1、认识c 、端正态度
首先,要问“如何学好c ”这个问题之前,必须先审问一下自己,“真的想把c 学好吗?”当然,问这个问题的人多数还是真的想把c 学好的,那么首先我们必须先正视c ,要正视其难度,我们要先认识c 。
c 是一种普通的高级编程语言,但从学习难度上,可以说它是最难学的一门编程语言了,它之所以难正是因为它强大的功能和灵活性。其中较难掌握的有指针、继承和模板,它不是一种适合快速开发的语言,而且想学好用好c 也不是一朝一夕的事,如果想通过java培训班那样通过两三个月培训,就可以培训出来可以用好c 并完成稳定的商业应用程序,那就是大错特错了。
除了其语言特性本身的难度,还有就是c 涉及到的一些其它必须知道的相关计算机科学知识。
1)c 程序不是一种非托管代码,不像java或c#等语言那样有一个虚拟机帮助我们管理内存,这样就要求c 程序员要理解内存的管理机制,要会自己管理内存。
2)c 程序一般都是与操作系统关系比较密切,很多与操作系统相关的问题我们必须清楚,每写一行代码,我们都必须清楚地知道这会对操作系统造成什么影响,如内存泄漏可能导致整个主机都会因为内存不足而无法运行,而java虚拟机一般都设置了上限值,至少不会吃完系统的所有内存;文件句柄泄漏,可能导致程序占完句柄后再不能打开新的文件;再如进程描述符泄漏,就是使用popen打开的进程如果不使用pclose关闭,会导致程序占完整个用户的进程表,导致该用户再也无法创建新的进程,如果该用户是root那么除了关闭电源,基本没有可能再进入系统了,这对于那些重要的服务器来讲是不可忍受的。
3)不要认为学会了c语言就离c 很近了,不要轻易听信c 只比c语言多了类和模板之类的话。因为类和模板相关的特性及语法规则数量,要比c语言的语法多得多,比较一下c语言的标准与c 的标准就知道了,而且c 的目的是面向对象的编程语言,我们要用好c 还必须理解面向对象的编程思想以及设计模式等技术。
总之,c 之难,不只是因为c 语言本身很难,还因为与之相关的很多知识都要深入理解,在遇到问题时才能迎刃而解。所以,如果想学好c 、用好c 必须把操作系统相关的知识搞清楚。要真正地理解c ,还必须把微机原理搞明白,这样才能真正地理解指针到底是什么东西等一系列问题。
如果真的想学好c ,就必须正视这些问题,真正不怕困难,循序渐进,坚持不懈。
2. 全面了解c
一定要找一本c 的经典书,把c 的所有特性读至少一遍(比如《c primer》、《the c programming language》),并且要理解该特性的用法、使用场景,要全面了解c 有哪些特性、这些特性有什么用。在第一阶段,还不一定要全部记住所有特性的语法规则,但必须要记住这些特性什么时候会用到,当真正用到的时候再回过头来看一下书查一下手册,不断地掌握这些技术。
本人认为,无论学习任何技术,首先不是如何使用该技术,而是全面了解这项技术,并清楚该技术可以帮助我们完成哪些工作,给我们带来什么好处,这样在我们日后学习、工作中在适合使用该技术的时候我们才能想起来使用这样技术。而具体如何使用,往往在使用时多看一下资料、查一下手册就可以满足我们的需要。
3、重点突破,勤于动手,学习致用
一下理解并记住所有的语言特性显然是不可能的,可以给工作不断使用新的特性,并趁机把相关知识了解全面,理解清楚。
在学习任何一项特性都应该把该特性通过一个示例彻底弄明白,记住语法规则,弄清使用场景。只是把书看一遍,或只是简单的一次试验,是不可能熟练掌握某个特性的,还需要在实际使用中不断理解、体会才能真正掌握。然后根据该场景再比较不同特性的实现方式,从可读性、易维护性、性能、编码量、使用难度等方面来比较各种方法,在以后使用中就可以信手捻来合适的方案,达到游刃有余的境界。
学习编程语言跟学一种人的语言其实是有异曲同工之妙的,都必须多“说”才能越“说”越流利。学习编程语言就要多编码,但不是重复的编码,要边编码边思考,不断在重构中提高代码质量,也就是要提炼我们所说的话,久而久之就会越来越准确,越来越精炼。
4. 多读书
一本书只能代表一个人或几个人的难点,所包含的智慧也是有限的,而且限于篇幅,所讲的知识都是有限的,通过阅读不同的书,综合各书中讲到的知识,才能不断扩大知识面、开拓思路;思路开阔了,解决问题的方法才能更多,最终的解决方法才能更好。
在读书的同时,不断重复相关的知识点和技术,也是加深记忆。
本人认为,书要选经典,一但选定就应该完整地读完一本书,不应把书看作手册偶尔翻阅(手册类书除外)。不可以把书当成搜索引擎的数据库,像使用google一样,搜索到解决方法把问题解决了之后就算完事,这样永远不可能成为高手。当然遇到难题使用google可以很快地搜索到相关的知识,但这并不等于可以不读书。因为书与杂志还不一样,它具有完整的体系,有很强的系统性和完整性,而使用搜索引擎找出的答案是不完整的、不系统的,我们就不能全面了解相关知识,当然就不能够做到举一反三、融会贯通。
比如essential c , thinking in c , exceptional c , more exceptional c , effective c , more effective c , exceptional c style等都是必读书目。
5. 多读源码
通过阅读较好的开源代码,可以开拓眼界,可以学到很多编码技巧、工程组织技巧等,这些技巧或方法很难在书上找到。 比如一些好的c或c 项目:lua、boost、chrome(google浏览器)、linux及相关(虽然是c的,但c 是c的超集,学习c语言也可以提高c 水平)、libwww(里面一种封装思想还是不错的,类似面向对象的思想)等。
除了阅读别人的代码,阅读自己的代码也可以有效地帮助自己提高。不论是新手还是熟手,三个月以后再回过头来看自己写的代码,恐怕都不敢承认这些代码是自己写的,经常会发现有很多可以改进的地方。因为此时我们已经忘记了当初的自己,现在可以以第三者的身份来审视自己,会把自己看得更清楚自己的弱点,有利于提高。
6. 多交流、帮助别人
多看一些好的博客文章,或在论坛上进行讨论,或者加入一些比较好的邮件组等,可以通过这些交流发散我们的思维和视野;
俗话经常说“比上不足,比下有余”,总有我们可以帮助的人。当我们学习c 到了一定程度,我们应该主动去帮助那些需要帮助的人。或许这个人就是你的同事,还可能是你潜在的竞争对手,但我们仍然应该去帮助他们,可以把自己比他们熟悉的技术教给他们。因为在给别人讲解的过程,不仅是我们温习的过程,同时也是我们重新思考、系统化所学知识的过程,只有我们真的理解了、掌握了,才能去教别人。“尺有所短,寸有所长”,我们讲解过程中肯定会或多或少有些不太清楚的地方,讲解的过程也就是交流、学习的过程。通过给别人的一次讲解,自己会更清楚、更系统地掌握这项技术。
7. 多思考 、举一反三
c 作为一门计算机语言,其实很简单就是一堆规则的集合,只要掌握了这些规则,也就掌握这门语言,它没有人的语言那么灵活多变,比学习一门人的语言简单得多,但同样它有很强的表达能力,同一个问题可以使用不同的方法解决。如果在解决任何一个问题的同时都去思考还有没有其它的ag真人游戏的解决方案,有没有更好的方法。在探索其它解决方法的同时也是温习其它适应点、给各个特性之间添加一种关系的过程。这好比原本孤立的一些问题和解决问题的方法之间使用线联系起来,这样日后一旦提到一个问题或一种方法,就会想到其它的问题或方法,久而久多就可以对知种问题、各种技术熟悉掌握。
8. 多写总结、力求准确
把博客当成一个笔记本,每学到一种新的特性或发现一种新的技巧就把它写下来。其实写的过程比用语言讲要难很多,说话可以很随意的,但写下来之后,就好比可以看到自己说的话,然后还可以把自己说的话重新“听”一遍,然后再重新组织一下,不仅温习的所学知识,还可以更规范地组织语言,更便于日后的交流。
另外,在写文章时一定力求准确,对任何拿不准的问题都应该认真求证,不断固化我们的知识
9. 学习其它的编程语言
c 和java、c#都是c语言的后裔,与c语言具有类似的语法结构,甚至很多语言特性都是相通的,但它们之前又有很多不同之处,语法特性也各有优劣。而c#、java的诞生就是为了解决c 中的一些问题(特别是资源管理)而诞生的,都是为了更快速、可靠地开发应用程序所设计的,对这些语言改进的方法也是我们可以用于解决c 语言本身问题的一些很好的ag真人游戏的解决方案。
比如java和c#中的引用类型,其实就是c 中的指针,但经过了封装,好比是c 新的tr1库中的shared_ptr,这两者的本质是相同的;c#中的delegate类型也与c 中的函数指针类似,但经过封装之后使用更灵活、方便、安全;c#中的property定义方式是c 中不具备的特性,但它对于数据封装却提供了很大的便利,使得编码很方便,虽然java中的bean通过方法名的约定也可以起到同样的效果,但使用起来就不太方便,不便于编译器自动检查。
10. 培养兴趣
“兴趣是最好的老师”,但是我把它放在了最后,因为前面的一些都可以强迫自己去做,即使不喜欢c ,这些事做多了也能把c 学好,但兴趣却是强迫不来的。如果想真正地成为c 高手,用好c ,没有兴趣是很难的。
比如,c 的语法其实是很美的,比如一个函数或代码块的开始、结束使用一对花括号就可以了,这比起vb中使用begin/end对要简洁得多。本人是非常喜欢c 的语法的,再如类的继承,简单的一个冒号就可以了,不像java还需要使用extends、implements关键词。的确extends、implements更接近人的语言,但我们是给计算机用的,只要人看着方便、阅读方便就可以了,为什么非得使用这么长的字符串呢,是怕程序员加班不够多吗?(:~)
记得一次面试一个应聘c 职位的同学,问了几个简单的技术问题都答不好,最后我问一个问题“你平时都看什么书?”,回答是:“《时尚》杂志……”。且不说这位同学的回答不合时宜,很诚实,既然没有基础有没有兴趣,我怎么能相信会把c 学好,然后做好工作呢?