如何学好C语言
有人在酷壳的留言版上询问下面的问题
keep_walker :
今天晚上我看到这篇文章。
http://programmers.stackexchange.com/questions/62502/small-c-projects我也遇到了和提问的老外一样的问题。。能给像遇到这样烦恼的程序员一点建议嘛?谢谢!
我相信,这可能是很多朋友的问题,我以前也有这样的感觉,编程编到一定的时候,发现能力到了瓶颈,既不深,也不扎实,半吊子。比如:你长期地使用Java和.NET ,这些有虚拟机的语言对于开发便利是便利,但是对于程序员来说可能并不太好,原因有两个:
- 虚拟机屏蔽了操作系统的系统调用,以及很多底层机制。
- 大量的封装好的类库也屏蔽了很多实现细节。
一段时间后,你会发现你知其然,不知所以然。。我以前在CSDN上写过一篇《Java NIO类库Selector机制解析(上,下,续)》,在那篇文章中我说提到过(有讥讽的语气)Java的程序员不懂底层实现,所以很难把技术学得更扎实。此时,一部分程序员会不自然地想学学底层的技术,很自然的,C语言就被提了上来。
下面是我给这位朋友的一些建议:
- 鼓励并为你叫好。我鼓励你想要去学C语言的想法和精神,很多人都觉得C语言好学,其实并不然。(你可以看看《C语言的迷题》)现在的这个社会更多地去关注那些时髦的技术,而忽略了这个流行了40+年的C语言。一门技术如果能够流行40多年,这才是你需要去关注和学习的技术,而不是那些刚出来的技术(过度炒作的技术,Windows编程史)。这才是踏踏实实的精神。
- 不要找借口。这一条路走下来并不容易,不要给自己找借口。我最不喜欢听到的就是“很忙,没有时间”这样的借口。我以前在银行做项目,早9点到晚10点,周一到周六,我一样可以每天抽1个小时来看书和专研,一年下来也能精读5、6本书。我现在的工作项目和招聘任务很紧张,刚生的小孩只有自己和老婆两人带,还需要准备讲课,但是我还是能够找到时间看文章写文章维护酷壳。所以,我可以告诉你,“时间就像乳沟,只要你肯挤,就一定会有”。
- 学好C语言和系统编程。我认为,学好编程有四个方面:语言、算法和数据结构、系统调用和设计。
- 语言。我可以告诉你C语言有两大主题你要好好学,一个是内存管理,一个是指针!这个世界上90%以上的C/C++出的严重性错误全是和这两个有关。不要看谭浩强的那本书,那本是本烂书。推荐这本书给你《C程序设计语言(第2版·新版)》
- 算法和数据结构。我认为,用C语言实现算法和数据结构莫过于最爽的事情。推荐你看这本书——算法:C语言实现(第1~4部分)基础知识、数据结构、排序及搜索(原书第3版),还有那本经典的《算法导论》
- 系统编程。Windows下推荐两本书——《Windows 程序设计 》和《Windows核心编程》,Unix/Linux下推荐两本书——《Unix高级环境编程》和《Unix网络编程卷1,套接字》《Unix网络编程卷2,进程间通信》尤其是《Unix网络编程》这本书,一通百通,无论Windows还是Unix/Linux,都是一样的。
- 系统设计。关于设计方面,我全力推荐《Unix编程艺术》,看完以后,你就明白什么是真正的编程文化了。然后,当你看到Windows的Fans的某些言论时,你就知道什么叫一笑了之了。
如果你能在2-3年内精读完这些书,并全部融会贯通,那么你就明白什么是一览众山小的感觉了!我足足花了5年时间才算是真正全部读完这些书的。最后,祝你好运!努力!
——-更新:2011/03/29 20:00——-
我想,这篇文章主要想告诉大家这么几件事:
- 编程编到一定时候,你就需要了解底层系统的机制,否则,知其然不知所以然。
- 我没有否定非C的程序员的逻辑,真正的逻辑是——如果你想要了解底层机制,请学习C语言和操作系统。
- 40多年的Unix/C影响深远。包括影响了Windows。如果你想一通百通,一定要了解Unix。那是计算机文化真正的根。
- 不要肤浅地去思考问题。比如,不要以为一个DBA就不会考虑数据库引擎的内存页面的问题。也不要以为Web程序员就不需要了解后台的服务器和脚本的运行性能以及TCP/IP的问题。
高手往往都是有很强的系统的基础知识的,表面的东西永远是肤浅的。
(转载本站文章请注明作者和出处 酷 壳 – CoolShell ,请勿用于任何商业用途)
《如何学好C语言》的相关评论
原来还有 Windows Fans这么一说啊……
我身边就有一个windows fan,他说过的一句话让我印象深刻……
“linux到处都是sudo,没有高级权限用着不爽”……
我研究C++的时候,他吐槽说这个世界以后会是由C#组成的。
准确地说这个家伙不是windows fan,是M$ fan……
……其实我想说的是,APUE只能当参考书用,如果想要体验*nix编程的乐趣,这本书可能更合适一点:
http://book.douban.com/subject/1219329/
看了之后觉着写的很笼统(不客气的说有点不负责任)。狭义的讲,C语言是一门很简单的语言(宏、结构(包括联合)、函数、数组、指针、字符串等),很容易学。但由于操作系统都是C语言写的,所以C语言广义的讲又与操作系统紧密的结合。但是为什么总会引申出Windows Fans与Uninx(Linux) Fans之争呢?哎,在我看来程序员反而是一群很狭隘的群体。
想多了
简单???你是指哪里简单
“Java的程序员不懂底层实现,所以很难把技术学得更扎实。” 每次看到这种说法我都郁闷一下. 小时候一直都是用C/C++的, 也写过DOS下的TSR和驱动, 大学时读的是EE, 自问对CPU和OS的理解还是比很多CS的同学要深的. 毕业后为了谋生就选了Java…然后就一个”java程序员”标签就把之前一大段人生给否定掉了.
我无意否定Java程序员或是Windows程序员,我想说的是,如果你要相对扎实的编程,你就需要了解操作系统、算法和数据结构。而Java的虚拟机和大量的类库让你不再关注这些细节。虽然对编程有利,但是对程序员的能力提升是无益的。
这世界上绝大多数的程序员都是CRUD或者CSS+JS程序员吧. 有什么理由去学习底层啊.
我想说的是,底层不等于扎实.程序员的能力除了写一些算法之外,还有更多的方向.
@陈皓 呵呵, 抱怨一下而已, 不是针对blog主的, 跑题了.
C语言入门的话, 我推荐一本叫的书, 清华出的, 里面有对C语言里一些很隐晦的东西有很好的说明, 很实用.
@陈皓
上面的回复过滤了书名, 书名是: C语言编程常见问题解答
C除了C圣经之外我认为还有《C专家编程》、《C缺陷与陷阱》、Richard Blum的《汇编语言程序设计》、国内的《程序员的自我修养–链接、装载与库》这几个看了才能对底层有个透彻的了解。
好在这些在毕业前已经基本都看过了,虽不说精读也算掌握脉络。
我也已决定追随Unix系平台
在C++人人喊打的时代我又决定重新学习C++,结合设计思想把她当作一门全新的语言去学习
书越是看的多越是感觉自己是井底之蛙,越不敢说XXX是垃圾、过时之类的话。
@wetwoo
这不是狭隘与否的问题,就像社会有资社、人有男女、天有昼夜一样,是一种归类,程序员是一个善于总结、抽象与归类的群体!
C是容易学,但难精;不信的话让你描述下
void (*(*((*prtn_pfuncarr)(void (*)(int), void (*)(int), void (*)(int), void (*(*)[])(int))))[])(int);
是什么? 你肯定会说这种东西没用! 对,实际上是没用,就像数学,你实际工作很少有正儿八经的用到过,但那确实基础思想。
@的份额 你说的没错,这世界上还有很多Web程序员。我这里只是想告诉大家一个纯正的CS计算机科学专业的程序员应该学习的东西。
@楼兰 你说的很对!C语言并不容易,能学好C语言的人,基础都是很强的人。这里有一篇《C语言的迷题》,大家可以去看看。
偶们这学期开始学 C
博主这篇提到的肯定很有用~
上次 wowubuntu 内个咆哮文提到了谭浩强 认真看了下书才知道什嘛叫闭门造车…
个人认为:单从语言层面上说语言的“好”与“坏”其实没有多大的必要,毕竟不同的语言适用于不同的环境。很多底层爱好者(包括我)认为C很好、无可替代什么的,甚至对Java、C#之类不屑一顾,我认为这些人的出发点是“彻底搞懂底层”,而在这个出发点上讨论总会有失偏颇。我认为最重要的是掌握编程的思想,而不单单是针对语言。我想C之所以受到大家的宠爱,原因之一就是它没有asm繁琐(事无巨细)又比流行的高级语言繁琐吧。
algorithm in C最大的好处是即使是比较复杂的数据结构和算法都给出了源码,并且设计上足够抽象….
受教了
请问,如何学好C++
说错了,给源码的是那本with C的不是in C的@pingf
正在学C,来的好及时,
@陈皓
虽然您这么说,可还是能听出您对Win程序员的讥讽。我见过最好的程序员是Windows、WinCE下的(以前公司的同事),是我身边唯一一个能给WinCE内核打patch的人(微软有很多BUG)。擅长逆向工程、系统编程。我想说的只是Windows下烂的程序员比Linux下烂的多很多,但请不要贬低那些剩下的牛人。OS层面,Win和Linux的差别不会太大的。如果M$放开Windows的源码,我相信全世界的程序员都会为之精妙而赞叹。
这个话题容易让人陷入口水战。会让很多人找极端的例子来极端化。我的感觉是这篇文章的意义主要是想说明学习C语言更有助于我们对系统进行深入的了解,没有贬低和抨击谁的意思,只是给大家一学习的建议,别无他。
其实刨根问底的态度才是最重要,不过这种态度 体现在编程上往往是对底层实现的关注而已。即使是使用高级语言的程序员,如果能多关心编译器本身对语言特性的实现,一样可以更好的提升自己的功底,更好的利用好语言的特性。
题为如何学好,但是文章似乎是在讲学好C的好处
本人在读Unix/Linux的内核代码,刚入门,看了UNIX的代码我就觉得,其实C语言的优势在PDP的机器上体现得最好,而在x86上系统和硬件的保护机制已经遮蔽了大量楼主说的“底层实现”。
没有好与不好的程序语言,只有好与不好的程序员,什么样的开发用什么样的语言了解什么方面的知识,如果要一个数据库设计师去了解内存页面的分配那我感觉是有点过分了
是选择C还是C++好?
@peija
如何学好C++,这个我觉得C++程序员要向Java借鉴了。我改天新开文章讨论吧。
@Phoenix
C和C++都好,我觉得C++在语言层面更为强大。不过代码规范和OO设计的功力要求得更高,C++不是什么人都能玩好的。
To All,我想,这篇文章主要想告诉大家这么几件事:
1)编程编到一定时候,你就需要了解底层系统的机制,否则,知其然不知所以然。
2)这是没有否定非C的程序员的逻辑,真正的逻辑是——如果你想要了解底层机制,请学习C语言和操作系统。
3)40多年的Unix/C影响深远。包括影响了Windows。如果你想一通百通,一定要了解Unix。那是计算机文化真正的根。
4)不要肤浅地去思考问题。比如,不要以为一个DBA不会考虑数据库引擎的内存页面的问题。也不要以为Web程序员就不需要了解后台的服务器和脚本的运行性能问题。
高手往往都是有很强的系统的基础知识的,表面永远是肤浅的。
来晚了,凑个热闹,学习。
拜读
皓哥,不知道这本书你有没有看过,叫<>http://product.china-pub.com/196897不知道这本书怎么样.据说很好,但是我英语超级烂,不知道啥时有个牛人翻一下.
唉 什么东东啊,书名都没了. 重写下,叫 C语言接口与实现:创建可重用软件的技术 地址在 http://product.china-pub.com/196897
推荐的那些书,都是经典啊!
我还真没有看过这本书,不过,关看看目录和Amazon的书评就知道这本书相当的专业。非常值得一读。感谢推荐!
首先,赞同:“我认为,用C语言实现算法和数据结构莫过于最爽的事情。” 深有同感,不过,提议几句,C算法实现确实是好书,但是我以为,最好搭配算法导论,和数学分析这两本书来看,这几本书是我床头书,前者告诉你怎么用算法解决问题,中间告诉你为什么能这样解决,后者则提供理论认证
@老栋
相当赞同。你说的《算法导论》也是一本经典的书。
看过楼主的帖子,只有两个字”精辟“。
楼主的意思是,程序员若要得道,一定要苦修行。大家何必从其他角度来评说楼主的不正确之处呢?
从一个C程序员,变成一个java程序员,这是一条怎样的路啊? 我现在正在这条路上。@陈皓
做javaweb的,这几天正打算开始学习C,赶巧看见楼主的好文…呵呵,在看一本 c语言程序设计现代方法(第2版)http://product.china-pub.com/196384 比较厚实,500多页,不知和您提到的 C程序设计语言 相对来说哪个更适合学习呢
白天工作不能上网,-_-。 晚上上来迫切的看到您的回复。真是相当的受教啊。谢谢博主!
书单可以加个《深入理解计算机系统》,把汇编、计算机系统结构、OS和C融汇贯通的入门读物。
看那么多评论,有些不乏好的建议,有些争论也很值得思考,不过那些 不“是”即“非” 的想法实在是有点让人受不了。
@壮壮
这本书很早就有中文版了,机械工业出版社出的
@陈皓
做javaweb的,这几天正打算开始学习C,赶巧看见楼主的好文…呵呵,在看一本 c语言程序设计现代方法(第2版) 比较厚实,500多页,不知和您提到的 C程序设计语言 相对来说哪个更适合学习呢
@楼兰
呵呵,为什么写的晦涩难懂,这就是狭隘,为什么不与人方便与己方便。如下:
typedef void (*pfunc_void_int)(int);
typedef pfunc_void_int (*pfunc_void_int_array)[];
typedef pfunc_void_int (*pfunc_xia_ai_and_bian_tai)(pfunc_void_int, pfunc_void_int, pfunc_void_int, pfunc_void_int_array);
typedef pfunc_void_int_array (*pfunc_xia_ai_and_tai_bian_tai)(pfunc_void_int, pfunc_void_int, pfunc_void_int, pfunc_void_int_array);
pfunc_xia_ai_and_tai_bian_tai prtn_pfuncarr;
就个人学习C的感觉而言,同意博主的观点,的确是C描述算法让人看的最舒服。同比学过Java版和其他OOP语言版的,还是C版的最为清爽,最关键是用C进行算法实现不采用OOP的思想,因此少了很多繁复和隐藏的东西,让人把流程一目了然,对于算法的每个小细节,可以嚼到最烂,分析到事无巨细,这样对读者为最好,尤其是刚入门的读者。用C来实现,所有最小的细节均暴露在外,所以一旦搞明白就是彻底的懂了,其他OO语言在描述算法时增加了阅读的复杂性,因为OO思想的引入,使整个问题的描述变得不简洁,读者就要花费不少额外的精力在搞懂这个思想上面,而无法专注于算法本身,想搞懂OOP肯定是比搞懂基本的算法要难的多,先放一放更为策略。
谭浩强的书错误很多,这是因为“历史”的局限性,现在C的好书太多了,直接看最经典的某一本,比如博主推荐的我看过,是很好,保证刚入门时不要被坏思想和习惯污染,不要浪费时间在那些过时的国内教材上,当然,这是事后才能体会到的。
对于win和linux,一般想同时扛起两个平台学习的人,最后能到精通的,肯定比只专注一个少的多,如果有充足时间,那么除了win,依然需要学习,可以学的东西太多了,因此,结合个人情况,慎重选择,兼顾以后的饭碗,才是明智的。
“时间像乳沟,只要挤就一定有” ,妙,只要对编程感兴趣超过玩游戏,那么想挤时间就自然一定会有。
@陈皓 这本书的确相当之专业,现在还不敢去看。。
相当同意一个观点,那就是C语言必须从
C语言的代码 -> 编译后的可执行文件 -> 运行时的内存状态 来学习,这个过程中需要将编程语言的原子组成部分(数据 + 代码)在这3个阶段进行学习,比如在 C语言的代码 中首先是学习C的基本的语法,标准库,然后是针对(数据 + 代码)的,数据是 数据结构和数据库,代码是算法知识,然后针对数据 + 代码总体的是面向过程的编程思想(与此同时,还需要学习将 数据 + 代码 理解方法有所不同的 面向对象和函数式思想(推荐SICP)),然后是编译后的可执行文件,这里就是学习编译原理的知识,然后运行时的就是操作系统的知识,这里最好结合操作系统的api一起学习(CSAPP+APUE),关于APUE,相当同意ls说的是查阅的,推荐2本《Linux C程序设计大全》 《Linux C编程一站式学习》,都是由浅入深的。
另外,个人感觉作者给的书都较高层了点,推荐下面2篇文章吧:
http://sunxiunan.com/?p=1661
http://learn.akae.cn/media/pr02.html
其他方面的话,作者加了些关于心理学方面的东西帮助学习,这是很好的但是也讲的少了点,推荐刘未鹏的blog(mindhacks.cn)
谢谢各位,你们的补充也让我学到了很多。
C语言接口与实现:创建可重用软件的技术 确实很不错 很多开源C项目也或多或少涉及该书里面内容
@wetwoo
简单就是美,正因为简单所以强大,哈哈哈。