你已经是个成熟的985大学了,请不要在大一教 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 写的 。
如果没 C 的基础 , 连实验都没法继续 , 而这些实验算是操作系统课程的精髓了 。
所以这才是我认为大一先上 C 语言的核心原因:
一是语法简单 , 更加贴近计算机本质的一些东西 , 学 C 也不是简单的学语言本身 , 而是想透过 C 语言去理解一些如寄存器、内存、函数调用、跳转等东西 。
二是为大二、大三阶段的专业课打下一个基础 , 当然很多同学说我不学 C 一样可以学操作系统、计网呀 。
当然 , 这些和 C 没必然关联 , 只是很多实验你确实不好继续做 , 除非你只打算看看概念 , 背背什么是进程、线程 。
三、如何正确的打开 C 语言?我认为 C 语言最为核心的有三块:
  • 指针
  • 内存
  • 系统编程
首先指针和内存是需要在学习 C 语言过程中就理解、搞定的 , 推荐两本书:
《C程序设计语言》、《C和指针》
如果你觉得初学看书过于困难 , 那么可以去中国大学 MOOC 上浙大翁凯老师的 C 语言课 , 可以直接去 B 站搜 。
视频结合书一起看 , 相信会理解得更加深刻 。
然后 , 学习完了 C 语言基本语法后 , 你会发现似乎只能开发在黑窗口里运行的程序 , 写不出那些漂亮的 GUI 。
确实 , C 语言本来就不擅长做这些 , C 语言擅长的是开发系统组件来支撑上层应用 。
但是如果你迫切的想做出一些可视化、有趣的东西 , 那么可以这样做:
  1. 找一些 C 语言的图形库 , 比如 easyx , 借助这些图形库 , 你完全可以实现一些图形界面的游戏 。
  2. 继续去学 Python、Java 这种语言 , 然后学习 Web 开发 , 写写网页 。
当然了 , 如果你对那些可视化的东西没那么大兴趣 , 甚至还挺喜欢黑窗口的 , 那么恭喜你 , 你有成为大佬的潜质 。
当你熟悉完 C 语言基本的语法以后 , 建议去学习数据结构与算法 , 用 C 语言去实现链表、树、二叉树、堆、排序、搜索等等 。
推荐看看《算法:C语言实现》这本书 。
如果能通过 void 指针实现一些泛型数据结构就更棒了 , 比如标准库里的 qsort 就能支持任意可比较结构体排序 。