【译文】您(也许)不需要学习 C 语言

我在 Mastodon 上写道,我已经厌倦了人们说 “你应该学习 C 语言,这样你才能理解计算机的真正工作原理”。我收到了很多回复,这些回复并没有改变我的想法,但却让我更加理解了抽象概念在计算机中是如何不可避免的。

人们提出了许多主张。C 语言很重要,因为系统调用是根据 C 语言语义定义的(其实不然)。他们说 C 语言有利于探索 Arduinos 等资源有限的计算机,但大多数人并不为这些计算机编程。他们说这很重要,因为 C 语言的性能更高,但 Python 程序通常会将计算密集型工作卸载到其他人编写的库中,而如今这些工作通常都是在 GPU 上完成的。甚至有人说 C 语言很好,因为它解释了为什么文件名中不允许使用 NUL,但谁会去做这些呢,为什么要为了这些琐事去学一门语言呢?

如果 C 语言对手头的工作有用,我支持学习 C 语言,但不懂 C 语言也能写出很多优秀的软件。

有一些人反复强调,C 语言教你代码如何 “真正 “执行。但 C 语言只是计算机的一个抽象模型,而现代 CPU 所做的一切,C 语言都无法向你展示或解释。流水线、高速缓存缺失、分支预测、投机执行、多核甚至虚拟内存都是 C 程序完全看不到的。

C 语言是对计算机工作原理的抽象,芯片制造商努力实现这一抽象,但他们是在更为复杂的机器上实现这一抽象的。

C 语言与现代计算机体系结构相去甚远:自 20 世纪 70 年代创建以来,C 语言已经经历了 50 年的创新。C 语言模型与现代硬件之间的差距是导致 Meltdown 和 Spectre 等著名漏洞的根本原因,正如《C 语言不是低级语言》一书所解释的那样。

C 语言可以教你有用的东西,比如内存是一个巨大的字节数组,但你也可以在不编写 C 语言程序的情况下学到这些。人们说,C 语言能教会你如何分配内存。没错,但你可以不学习编程语言,直接了解内存分配的概念。此外,Python 或 Ruby 开发人员除了感谢他们的语言为他们做了这些工作,让他们不再需要考虑这些之外,还会用这些知识做什么呢?

在 Mastodon 的回答中,我们经常提到指针。指针是高级语言概念的基础,但您可以用引用来解释这些概念,完全跳过指针运算、别名和空指针。

我问过很多人一个问题:如果 JavaScript/Ruby/Python 开发人员不知道这些东西(C、系统调用、指针),他们会犯什么错误?我没有得到有力的回答。

我们在一个巨大的抽象塔中工作。我用 Python 编写程序,它为我提供了 C 语言(其底层实现语言)所没有的抽象。C 语言提供了内存和 CPU 执行的抽象模型,计算机在其他机制(微代码和虚拟内存)的基础上实现这些模型。当我制作一台电线包裹的计算机时,我可以假装信号瞬间通过电线传输。而对于其他硬件设计人员来说,这种抽象概念会被打破,他们需要考虑电的传输速度。有时,你需要在抽象堆栈中再深入一层,才能理解发生了什么。每个人都必须找到合适的工作层。

安迪-戈克(Andy Gocke)说得好:

当你在那一层不再遇到问题时,你就可以不再关心那一层了。我不认为人们需要的或足够的知识有一个普遍的水平。

“like jam or bootlaces “提出了另一个很好的观点:

在 “每个人都应该知道这个 “和 “每个人都应该知道这个 “之间存在着很大的差异,而在这类讨论中,这种差异似乎被掩盖了。

C 语言能教会你许多有用和有趣的东西。它能让你成为一个更好的程序员,就像学习任何一门新语言一样,因为它能拓宽你的视野。某些类型的编程需要 C 语言,不过现在 Rust 等其他语言也能胜任这一角色。C 语言并不能教会你计算机的真正工作原理。它教给你的是计算机如何工作的普通抽象概念。

找到适合你需要做的事情的抽象层次。当你在这方面遇到困难时,就看看这个抽象的下面。你看到的并不是事物真正的工作原理,而是可能对你有帮助的低层次抽象。有时,你需要的是更上一层的抽象。你的 Python 循环是不是太慢了?也许你需要一个 C 循环。或者你需要 numpy 数组操作。

你(可能)不需要学习 C 语言。

本文文字及图片出自 You (probably) don’t need to learn C

余下全文(1/3)
分享这篇文章:

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注