为什么 C 语言不会过时 Shepard-Wang

今天看了羊哥(CodeSheep)微信公众号发的文章,认识了大佬 赵岩

点开他的博客,语言清晰干练,幽默风趣,期间我放声大笑几回。我不由得倾佩他的文笔和幽默。

我都这篇博客主要来和大家探讨他写的这四篇文章:

  • 为什么 C 语言不会过时 (http://zhaoyan.website/blog/index.php/2017/07/15/future/)

  • 什么教材适合零基础的C语言学习者?(http://zhaoyan.website/blog/index.php/2017/06/18/ctextbook/)
  • 为什么 C 语言很难? (http://zhaoyan.website/blog/index.php/2017/05/20/c/)
  • C/C++语言的五个层次(http://zhaoyan.website/blog/index.php/2018/01/20/c5/)

个人认为其中 《为什么C 语言不会过时》 和 《为什么 C 语言很难》 很值得一看 。

一 C/C++ 语言的 5 个层次

赵岩认为,C/C++ 分为:

  1. 熟悉了 C/C++ 的语法,认为自己”精通 C++“
  2. 开始动手去编写项目,遇到了问题,思考语法细节,并在 StackOverFlow 等这种网站上寻找答案
  3. 利用面向对象语言的特点编程
  4. 了解/实现 C++ 编译器(g++,Clang,VC++)
  5. 制定C++语言的标准

(PS:这屋子好亮啊。。。果然 C++ 很耗头发)

引用一段原文:

总结一下:整个的过程是这样,标准对编译器说,你听我的。编译器对C++语言说,你听我的。C++对实际问题说,你听我的。实际问题对程序员说,你听我的。作为程序员,你有两个选择。你可以说,我都精通C++语言了,我谁也不听。那你就可能一辈子停留在精通这个阶段。如果你选择,我听!那么好,你仔细听,你会慢慢地开始听见C++语言怎么说,编译器怎么说,标准怎么说。

二 什么教材适合零基础的C语言学习者

这篇文章中,作者并没有给你一个明确应该看的书单。反而有给自己打广告之嫌(我并没有指责之意)。原文中说:

我想说的是,教材就这么回事,大部分教材内容都差不多。也就是说,如果你看教材A没明白,那么教材B你也看不明白

这个观点我实在不能苟同。很多大学 C 语言的课程(包括我们大学)都是谭浩强老师的 《C语言程序设计》,这本书我不多做评价(大家可以上网自己查口碑)。它和 《C 程序设计语言》(The C Programing Language)的名字如此相似,仅仅是几个字换排了个序,可能还有什么书叫做《C 设计程序语言》,《C 语言设计程序》。。。但是在你买书时你千万不要买错,一定要买 《C 程序设计语言》。因为买了其他的书回去,你会陷入两难的境地:看吧,会浪费你的时间,不看吧,又会感到钱打了水漂。

如果当时我看的书不是谭老师的,而是 《C Primer Plus》或者 《C 语言程序设计——现代方法》这样的书,我肯定会少走很多弯路。所以,选择一本质量比较高的书入门,是相当重要的。等你学到了一定阶段,再回过头来看 《C 语言程序设计》和 《C 程序设计语言》,你会发现这两本书是不应该用来作比较的,因为没有任何可比性。

对于 C 语言和 C++ 语言我推荐大家两个 GitHub 仓库,上面有很多代码示例还有书籍推荐(和免费下载链接):

C

C++

但是文中提到:

如果再有人告诉你什么21天从入门到精通的话,你要提高警惕。骗子成功的主要原因就是我们都想不劳而获,切记!

和知识相比,技能不可能通过看书获取,因为技能的获取完全靠自己的实践。所以100%带有强制性,例如你的毕业论文,你公司的任务等。 你要忍受任务带来的压力,要面对现实中各种复杂的问题和挫折。实验,思考,分析,解决。在这个令你最劳累的过程中,你失去了头发,获得了技能。技能的获取没有捷径,拿C语言来说,别人都说C语言坑多,解决这个问题的方法其实非常简单,就是每个坑你就踩一遍!

不过我要恭喜你,根据能量守恒定律,失去头发而获得的技能是最值钱的。在你未来的生活中,你要靠你的技能来赚取你的工资,你的技能的水平也决定了你的生活水平。

这些我都是十分赞同的,学习没有投机取巧可言。就像赚钱,遇到了好的机遇,可能你会暴富;但是天天只想暴富而不踏实耕耘,最终只能自食恶果。

我也有 能量守恒 这种观点,人可能是情感最丰富的动物了,一会高兴,一会伤悲。你看自然界的动物,它就不喜不悲。就像寺庙里的高僧,一天面无表情,没有什么事情会让他们喜不自胜,自然不会有事让他们悲伤欲绝。往往电影院里感极而泣的,可能现实中铁石心肠,因为眼泪都留在了电影院中和电视剧上。

学习和人生是一样的,当你感到痛苦,说明你正在为未来的幸福添砖加瓦。就像周总理说的,低着头走上坡路。

看看这个大妈,我真是佩服他,我们还有什么理由不努力呢:

img

三 为什么 C 语言不会过时

对所有的编程语言,他们的最后的目的其实就是两种:提高硬件的运行效率和提高程序员的开发效率。遗憾的是,这两点是不可能并存的!你只能选一样。在提高硬件的运行效率这一方面,C语言没有竞争者!举个简单的例子,实现一个列表,C语言用数组int a[3],经过编译以后变成了(基地址+偏移量)的方式。对于计算机来说,没有运算比加法更快,没有任何一种方法比(基地址+偏移量)的存取方法更快。C语言已经把硬件的运行效率压缩到了极致。这种设计思想带来的问题就是易用性和安全性的缺失。例如,你不能在数组中混合保存不同的类型,否则编译器没有办法计算正确的偏移量。同时C语言对于错误的偏移量也不闻不问,这就是C语言中臭名昭著的越界问题。C语言自诩的“相信程序员”都是漂亮的说辞,它的唯一目的就是快,要么飞速的运行,要么飞速的崩溃。C语言只关心程序飞的高不高,不关心程序猿飞的累不累。就是这样!

伴随着嵌入和实时系统的兴起,AI,机器人,自动驾驶等。这些都是C语言的核心应用,而且在这种应用上面,C语言没有竞争者。所以我感觉C语言会稳定在自己核心的应用中,并开始逐步回升。但是Java语言我个人不乐观。小型和灵活性上,Python更胜一筹。一行python代码后,你根本不知道自己还是不是duck类型?平台领域,每个平台都推出自己专属的语言。Windows会继续支持C#,苹果偏爱Swift, Android推出Kotlin,Google用go。Java宣称自己可以自由到每家做客,但是无论是到谁家,都会发现客厅里面坐着一个亲儿子,这个时候自己这个干儿子多多少少有点尴尬。所以我猜测,最后Java会稳定在对跨平台有严格要求的,大型非实时应用上。

最后说点闲话,C++不会淘汰C语言。有了对象后你会发现再简朴的对象也耗费资源,而且有了对象以后,总是不由自主的去想继承这个事,一但继承实现了,你会发现继承带来的麻烦远超过你的想象。Java的发明人James被问到如果可以从新设计Java语言的话,第一个要做什么事?他说:“去掉对象”!作为一个已婚,有两个孩子的程序猿,我感同身受。如果大家感兴趣,我可以再写一个博客,聊聊C++和C的真实区别所在。

如果你看到这里,还什么都没记住。那就只记住一点:没人能预测未来。 -------------------------- 全世界只需要五台电脑 -IBM创始人 640K内存足够了 -微软创始人 没必要在家里用电脑-DEC创始人 -------------------------- 如果再有人对你说C语言已经过时了,最好自己思考一下,能求真最好,如果不能,至少要做到存疑。

看完了这些,有没有感觉重拾了对 C 语言的信心?你可能会说,C 语言这么难,值得去学习吗?下面解答你的这个疑惑。

四 为什么 C 语言很难

不同与JAVA和python,C语言面临的任务几乎都是要求实时,高速或者是嵌入的。例如医疗,军事,飞控,航天,金融等领域。举个栗子,NASA大部分软件要基于三个不同的时钟系统,自转(公转)时间,CPU的晶振时间和原子钟时间。一秒要分成500份,基于2毫秒的基础进行操作同步;同时用全球的原子钟时间均值对所有时钟系统调整。在这种环境下,JAVA那种“大约一分钟以后”的虚拟机管理方式一定是不行的。 所以我在NASA工作所接触的软件,几乎都是C语言编写的。可想而之,这种软件的开发难度,当你阅读这种程序代码的时候,你说C语言太难了,这是否有点不公平?

其次是开发环境难。C语言一开始就和UNIX(LINUX)有不解之缘,它们是伴生的系统。所以要想发挥C语言的全部威力,最好的开发环境就是UNIX(LINUX)系统。但是问题来了,UNIX(LINUX)系统里的各种开发工具,每一个都不是省油的灯。它们设计的最初目的就是效率,而不是易学性。再举个栗子,gcc的各种编译开关就很复杂了,make系统为了解决gcc的部分问题,自己随之带来了更大的问题。git目的就是帮你保存历史备份,但是你会发现你经常会串改历史,或者干脆迷失在历史中。就连最简单的一个编辑器VIM,头一个月内,你最多的使用体验就是“恨不得拽自己的头发把自己提溜起来。”

好吧,外面的世界太凶险!让我们回到Windows妈妈哪里。虽然Windows的大部分内核都是C语言写的,但是它对C语言的支持缺最差。Why?如果你用Window的编译器去编译C语言,你会发现变量必须要写到函数的开头。它是唯一一个只支持到C89标准的编译器。Windows本身不想去抢这份实时,高速,嵌入的市场,老老实实做消费电子市场就好,这种市场要求开发容易,发布快。所以C#语言和后面的.Net平台才是它发展的重心。像玩LEGO那样的编程,你需要做的就是把一个个控件拽到窗口上,用鼠标来编程!所以还是算了吧,毕竟你也不想你在做飞机的时候,飞机上控制降落的电脑突然蓝屏了吧!所以如果你是一个C程序员,你唯一能做的就是在linux下使用哪些臭名昭彰的难学的工具。这笔账难到也要算到C语言的头上吗?

好吧,外面的世界太凶险!让我们回到Windows妈妈哪里” —— 不能熟练使用 Linux 请不要说自己是程序员!

最后是底层难。这必须要要聊聊C语言两个最受诟病的特性,位操作和指针。这两个概念本身很简单。但是通过这两个概念,它把很多底层操作系统的知识和体系结构的知识都暴露了出来。指针指向地址后,马上引入了一大堆内存管理知识。什么是堆?什么是栈?这个地址在内存的那个区域?这个区域可以修改吗?这个区域自动回收吗?指针指向函数后,又引入了一堆操作系统知识,什么是回调函数啊?什么是事件驱动啊?以及位操作后面的二进制,溢出,浮点数精度等等一系列的问题。我用手指指向了一本《相对论》,然后就有人跑过来对我说,你这个手指头太难了!

我用手指指向了一本《相对论》,然后就有人跑过来对我说,你这个手指头太难了! ”—— 看到这里,我只想说妙啊!太妙了。

如果编程只是你的业余爱好,使用那种语言真的无所谓。大部分初学者面临的任务规模下,三种语言的开发难度都差不多。 就是打个招呼,英语的“hello”,中文的“你好”,或者是日语的‘牙买碟’,我实在看不出这有什么难度上的区别。但是如果你立志要当一名高水准的程序员,C语言你是逃避不开的。或者编程序是你的饭碗,你也要认真考虑一下C语言。语言的易学性在就业上是一把双刃剑。如果一个公司招聘C程序员,你第一个反应就是他为什么不去招聘满大街的JAVA程序员?你面临的一定不是什么图书管理系统,也一定不是一个什么网站。想明白了这一点,就完全有理由要一个高价钱!

这就是为什么我的大学教授 Java 而我要走 C/C++ 这条困难且枯燥的路线了。

C语言很难,要逃避这种难,却很难!C语言很简单,要理解这种简单,却不简单(文章排比对账,我只服自己!)

没有白白付出的汗水,你的付出总会在某一天以某种形式反馈给你,很多时候,只是时机未到罢了。

如果你刚上大学,那么你有很充裕的时间向底层学习,而不是仅仅停留在上层,这方面我也没有经验,不敢继续妄言了。

总之,这篇博客是想告诉你 C 语言并不是一个怪物,相反,它是我们计算机专业学生的朋友。和它交朋友,它会作为你的利剑,让你拥有挑战任何语言的勇气;它会成为你的灯塔,指引你穿过晦涩的底层。

你好,C 语言!