不会c 语言能学linux么,90%以上的大学大一都学C语言,为什么?其他语言不香吗?...

以下文章来源于公众号编程指北 ,作者编程指北

昨天晚上回家后突然在朋友圈发了个问卷,看下国内大学第一门语言到底有多少是用的 C 语言。

f9a6b18978ab0276bbee99c6f1984a13.png

结果也是很符合预期,使用 C 语言做第一门编程语言课的大学达到了 90% 以上。

9ed4cb5fbee24f100065ca4568e22b46.png

之前在知乎看见一个问题,问为什么还有985高校给大一上 C 语言课,如下:

fb08a28bdcc1aece5c73df13cd5c22c5.png

原问题

不过这个提问方式未免有引战嫌疑,所以被知乎管理员编辑为如下问题:

391c5d687332e3bba7a552611e7ba727.png

现问题

这样显然中立很多了,是在摆事实提问题。

接下来我们就聊聊 985 大学为什么还是给大一上 C 语言课。

一、为什么要学 C 语言?

首先,我们学的是 Computer Science,而不是 Programming Language,语言真的真的真的不是重点。

语言只是工具,工具没有优劣,只有各自适用的场景不同。

所以,以下所有讨论皆不涉及语言优劣,一切论述以怎样才是有利于学好 Computer Science 为原则(求生欲满满

大学教育,尤其是 985、211 这种国内最顶尖的一批高校,应该注重通识教育而不是专项教育,在专业上更要注重基础、底层、偏向原理。

只有掌握了最核心的东西,学起那些偏技能的东西才会很快很轻松。

我记得当时大二需要写爬虫,大概看了一天左右的 Python 教程,会基本的循环、判断、控制流、一些 builtin 函数和类,然后学了下 requests 库就直接开干了。

其实像 JS、Python、Node、PHP 这些东西,科班学生几乎都是自学,哪还用得上单独开一门课呀。

自学是最基本的要求,需要用到的时候自己去看教程、文档,直接就上手写了。

所以这种语言完全没必要开一学期的课来学,倒是非常适合放在计算机导论课程中,成为其中一个章节。

比如 Berkeley 开设的导论课 CS 61A 就是以 Python 作为练习语言,但是似乎国内很少有高校开这种导论课。

但是 C、C++ 这种语言,不学个一两个月,连个像样的程序都写出来,这种才是适合开一门课。

先说一下学习 C 语言的目的,上面我说语言不是重点,这也包括 C 语言。

但是 C 语言特殊就特殊在它可能是唯一最适合用来学习一系列计算机基础课的工具和媒介。

比如操作系统,实验几乎都是用的纯 C 写的 lab;

又比如汇编,学习的时候可以和 C 语言对应起来,了解if、for、while、数组访问等对应汇编是怎么样的;

又比如学习计网,这里面有很多的网络协议,会有不同的 header 定义,这些 header 中很多都是按 bit 来划分字段的,用 C 语言的 union 和 struct 是最好操作这些字段的,Java 和 Python 等语言虽然也能表示,但是可控性会差很多,以前尝试过用 Python 去组装 IP 包头,非常的麻烦也不优雅。

并且 C 语言本身抽象层次非常低,语法也很简单,没什么语法糖,很贴近操作系统。

而其它很多解释型语言会存在虚拟机这一层,虚拟机对我们算是一个黑盒,不利于透过语言去理解计算机的一些行为。C 语言被列为计算机专业的基础,而且是程序员必学的知识。

5830b00373680f318005535d38216afd.png

二、C 语言的优点

C 语言已经走过了四十多年的历史,但是在今天,任然常年霸占 TIOBE 编程语言排行榜前三,甚至榜首,这足以说明它是一门经久不衰的语言。

在日新月异的计算机行业,一个历经四十多年任然流行的技术,才是需要我们去关注和学习的经典。

C 语言是最适合用来理解计算机系统底层机制的语言,下面就详细说说,这些底层机制都有哪些:

内存

一名合格的程序员必须了解内存,学习 C 语言是了解内存布局最直接、有效的途径

堆栈

理解不同的内存分配和管理方式,一种编译器自动管理,一种是手动管理。

函数调用栈、返回值

理解函数调用的本质,即跳转指令,理解返回值是怎么返回的。

系统调用

比如理解文件描述符,知道文件、socket 这些都被抽象成了fd。

指针

指针也是其它语言中引用的基础,深入理解指针对于理解引用也有很大帮助。

就拿文件来说,在 C 语言 中经常会接触到 read、write 系统函数,清楚操作的打开文件对应的是文件描述符。

而文件描述符是有限的,所以你知道用完 fd 后要及时关闭。

甚至用到 socket 网络编程的时候会发现,socket 返回的也是 fd,居然网络数据也能通过 read、write 去读写。

深刻的体会到 Unix 哲学:一切皆文件。

而在 Java、Python、PHP 这些语言中,打开一个文件只需要调用 File.open 或是 open,然后就可以拿到一个对象,然后对这个对象去调用读写方法进行操作。

但这时候文件对于我们更像是一个资源,全部的细节都被对象屏蔽了,而老师说资源是有限的,所以用完了要及时释放。

而你也不知道如果不释放这些资源会有什么后果,只是听老师说用完的资源及时释放是个好习惯。

在这里,操作系统的文件系统、进程等很多实现机制就被 JVM、Python 虚拟机所隐藏了。

而和操作系统等密切相关的底层机制也只有通过学习 C 语言才能透彻地理解它们。

这里又有个矛盾,上面说的这些内容其实不单单是 C 语言课所教的,其中还包括《组成原理》、《汇编》、《操作系统》等。

所以就出现了很多同学说的,就算上了 C 语言课,上面这些很多原理也还是不知道呀。

当然,这些内容是需要在大二、大三上专业课逐渐补齐的,但是先学 C 语言给学习这些内容打下了一个基础,大一把内存和指针理解透彻就好了,这就是前置条件。

而如果大一不上 C 语言,那么后续需要用到 C 语言的时候,自学的难度会高于自学 Python、Java 等语言。

比如有些学校在操作系统课会引入一些国外的 Lab,诸如 MIT 6.828 xv6 那样的 mini os,需要学生动手去完成一些内存管理、多线程实现、文件系统等操作系统核心模块。

比如清华 OS 课程用的 ucore,哈工大 OS 课程用的 linux-0.11,这些都是纯 C 写的。

a43b0b523bd542eb37b51755c7a32e90.png

如果没 C 的基础,连实验都没法继续,而这些实验算是操作系统课程的精髓了。

所以这才是我认为大一先上 C 语言的核心原因:

一是语法简单,更加贴近计算机本质的一些东西,学 C 也不是简单的学语言本身,而是想透过 C 语言去理解一些如寄存器、内存、函数调用、跳转等东西。

二是为大二、大三阶段的专业课打下一个基础,当然很多同学说我不学 C 一样可以学操作系统、计网呀。

当然,这些和 C 没必然关联,只是很多实验你确实不好继续做,除非你只打算看看概念,背背什么是进程、线程。

三、如何正确的打开 C 语言?

我认为 C 语言最为核心的有三块:

指针

内存

系统编程

首先指针和内存是需要在学习 C 语言过程中就理解、搞定的。

然后,学习完了 C 语言基本语法后,你会发现似乎只能开发在黑窗口里运行的程序,写不出那些漂亮的 GUI。

确实,C 语言本来就不擅长做这些,C 语言擅长的是开发系统组件来支撑上层应用。

但是如果你迫切地想做出一些可视化、有趣的东西,那么可以这样做:

找一些 C 语言的图形库,比如 easyx,借助这些图形库,你完全可以实现一些图形界面的游戏。

继续去学 Python、Java 这种语言,然后学习 Web 开发,写写网页。

当然了,如果你对那些可视化的东西没那么大兴趣,甚至还挺喜欢黑窗口的,那么恭喜你,你有成为大佬的潜质。

当你熟悉完 C 语言基本的语法以后,建议去学习数据结构与算法,用 C 语言去实现链表、树、二叉树、堆、排序、搜索等等。

推荐看看《算法:C语言实现》这本书。

如果能通过 void 指针实现一些泛型数据结构就更棒了,比如标准库里的 qsort 就能支持任意可比较结构体排序。

然后,时间应该很快来到了大二、大三,这时候你应该学习系统编程,什么是系统编程呢,其实就是 CSAPP 这本书上所讲授的内容。

5b704170d66639814fd6bb58594d7b07.png

系统编程其实就是学习如何用 C 语言编写出真正可用的软件,比如像 http server、redis 这种,会涉及到:

如何在 Linux 环境下编程

系统级接口(system-level interface)究竟是什么

Linux 内核和 C 标准库提供了哪些能力

Linux 的系统调用是怎样实现的

都有哪些系统调用,如何使用

其它诸如mutex、signal、select、epoll、ipc、socket、thread、process(fork)等等

当然,还有一些同学会选择继续学习 Java 这种,比如 JVM、多线程、Java Web 等等,这也是没问题的。

但是,相信我,就算你以后不会用到 C 去编程,利用大学大把的时间去深入学习一些底层的知识。

也是对深入学习 Java 有好处的,比如你学 Netty、 Java 的 NIO 最终都要回到 Linux 系统的 epoll、select 上。

系统编程推荐《深入理解计算机系统》、《Unix网络编程》、《Unix高级环境编程》,Windows 下的我基本没学过,所以就不推荐了。

98393178120e70429fb0a6e4f178850c.png

虚拟机之下的世界

这就是 Java、Python 之下的世界,相信 Javaer 都学习过 JVM 的原理,了解过 GC、类加载机制、运行时数据区等知识。

但实际上,JVM 也只是介于操作系统之间的一个中间层。

很多时候 JVM、Python 解释器等本身都是需要 Native 本地方法栈去和 OS 打交道的,去和系统调用接口交互。

所以 Linux 系统编程对于深入学习编程一定是绕不开(因为很多服务端程序都是运行在Linux上的,所以忽略了Win/Mac

而这是 C 语言的世界:

30443c98bbfcdbbfc644be4d854ec90c.png

所以 C 的重要性不需要的多说了吧~

不少 Java、C#、PHP、Python 程序员工作几年后会遇到瓶颈,有些会回来学习 C 语言,重拾底层概念,寻求新的突破。

这里不是在否定其它非 C 程序员就没技术,实际上我本身也不写 C,我只是想表达如果你想学习底层机制、操作系统等,请学习 C 语言。

编程学到一定的时候,你就需要了解底层系统的机制,否则,知其然不知所以然。

真正的高手往往都是有很强的系统性基础知识的,表面的东西永远是肤浅的。

所以利用大学的时间恰恰是打好这些基础的关键时间,等到工作了,大家都是更倾向于学习快速上手业务的技能。

也许以后实际工作中你完全没有机会去写 C,但是这并没关系,打好了基础,学其它也会学得很快、很透彻。

对于计算机专业的同学,还是建议学好 C 语言,与其它课程相结合,多懂一点程序背后的实现原理。

总结一下,BB 了这么多,就想表达一个意思,C 语言很重要,如果你正在大学学 C,一定要掌握好,不要怀疑学 C 有没有用。

正好今天在评论区看到有网友评论,所以分享这篇文章,希望对你有用。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值