以下为译文:
“第一门编程语言学C靠谱吗?”
“C还有未来吗?”
“我应该考虑学C吗?”
“C太老了吧!”
你是否也听过类似的话语?我听说过无数次,有些是面对面的交谈,而有些来自某个论坛。虽然答案无非是“取决于具体情况”,但以我的拙见,学习C编程是非常宝贵的经验。
我想通过这篇短文向你展示C伟大的一面。
C的精神
首先,我想引用文档C99RationaleV5.10中的一句话:
C89委员会始终将保留C的传统精神作为主要目标。C的精神体现在很多方面,但其本质在于社区对C语言所依赖的基本原则的看法。C的精神可以总结为以下几个方面:
-
相信程序员。
-
不阻碍程序员完成任务所需的工作。
-
保持语言短小精悍。
-
仅提供一种操作的方法。
-
保持高速,即使无法保证可移植性。
下面,我将进一步讨论上述几点。
中级编程语言
编程语言可以大致分为两个级别:低级和高级。
低级语言靠近硬件,比低级语言更接近 CPU 的就只有电流了。这些语言又分为为机器码和汇编两种。前者是原始数据流,通常是二进制数据。为了便于人类使用,通常我们以“可读”的十六进制形式进行处理。
第二代语言汇编在机器码之上提供了一层抽象。这些语言大部分是人类可读的符号(包括符号地址)、操作码、地址、数字常量、字符串等的映射。而且每个处理器各有不同。
相较而言,高级语言提供了哪些抽象?根据维基百科:
与低级编程语言相比,高级语言使用了自然语言元素,更易于使用,而且还可以自动化(甚至完全隐藏)计算机系统中的重要领域(例如内存管理),从而简化程序的开发过程,而且也比低级语言更易于理解。编程语言提供的抽象数量决定了其“高级”程度。
简而言之:低级语言=更加靠近机器,高级语言=更加人性化。
C 是高级编程语言,但在 C 刚刚创建的时候,大多数功能仍然是通过低级的汇编完成的。因此,与其他广泛使用的语言相比,C 拥有更底层的抽象级别,因此我喜欢将其称为“中级编程语言”。
你可以轻松地将 C 代码编译成汇编(而不是二进制代码),并检查 CPU 执行的指令,在这个过程中C语言不会加入太多语言特有的代码。
此外,如果有需要,流行的 C 编译器还提供了更低级的选项,允许你使用内联汇编完全掌控 CPU。纵观编程领域,能够做到这一步的编程语言可谓少之又少。
简洁
低级语言的编程难度很高。不是因为这些语言过于复杂,而是因为这类编程很容易出错,因此需要投入更多精力、记忆和心思。
C 是中级编程语言,因此“根据定义” C 语言编程更加容易。但令人惊讶的是,与高级语言相比,C 语言的学习非常简单。为什么?因为 C 语言的语法非常简单,还有结构化的范例。循环、函数、结构、指针、变量、类型等核心基础知识的学习都非常容易。大约只需一周的努力学习即可入门。剩下的就是数学和计算机科学理论了。
但是,不要误会我的意思!如果想完全掌握 C 语言,你需要付出大量的努力!事实上,学习任何东西都需要付出大量的努力!
快速、轻量级
与其他语言(例如 Java )相比,标准 C 库很小,所以你完全可以记住所有的功能。虽然有些功能应该在很久以前就弃用了,但是 C 语言的性能仍然非常出色。
如果连 libc 都觉得太大怎么办?即便你完全不用 libc 也没有关系。只要不包含括任何头文件即可,甚至连简单的 printf() 都不使用。你可以将其替换成其他库。
C 语言非常成熟,重视对内存的管理,拥有内联汇编、少量抽象,且语言没有过度膨胀,因此程序员能够很好地控制程序。
因此,C 语言成为了 OS 内核(Linux、Windows NT 或 macOS 的 XNU 等)以及其他语言(例如 Python)的理想选择。这也是为什么 C 在嵌入式系统上如此受欢迎的原因,因为嵌入式系统不允许浪费任何资源。
无所不在=可移植性
你能否想到任何没有 C 编译器的重大平台?除了有些只运行汇编的平台,我从未听说过没有 C 编译器的平台。高端游戏 PC、NASA 航天器、售票机等各种平台都使用了 C 编程。真的是无所不在,C 软件遍布全世界。
如上所述,对于围绕在我们日常生活中的微控制器和其他形式的嵌入式系统来说,C 语言是主流选择。
你听说过FFI吗?事实证明,许多编程语言都可与 C 兼容。
你不必担心是否可在某些工作中使用 C 语言,99%的情况下你都可以使用 C!(尽管这并不意味着你应该在所有工作中都使用 C……)。尽管 C 语言的代码并非100%可移植,但你可以成为可移植的程序员。
影响力
C 语言直接或间接地影响了无数语言,比如 C++、Java、Go、D、Rust、Perl,甚至是 PHP 和 Python。
显然,学习这些语言的时候,你并不需要 C 的知识,有时甚至还不能使用C的最佳实践。
然而,我认为记住编程语言的根源很重要。而且,如果你熟悉 C,那么就会有一些优势,尤其是 C++ 的学习。
丰富的库
我怀疑以上对于 C 语言的快速、轻量级、中级编程语言、汇编等方面的讨论,可能会给你一个错误的想法:你需要实现所有的功能。虽然 C 确实没有 Java中的 LinkedHashMap 或其他功能(如垃圾收集器),但 C 语言也不至于那么落后。
C 是一种成熟的流行语言。无论你需要何种功能,相信都能找到相应的库(虽然有些功能太晦涩不容易表达,因此不太好找,但我相信这些库一定存在)。
你需要垃圾收集器?那么可以试试 Boehm GC。你需要 TUI?那么 ncurses是不二的选择。还有很多很多库,我无法一一列举:GTK、PDCurses、libcurl、ALSA、Genann、libsoundio、SDL、SQLite、getopt、OpenGL、inih、GMP、cJSON、MuPDF、OpenSSL …
C 是一种非常通用的语言,基本上可以编写任何东西:Web服务器、视频游戏(例如来自 id-Software 的经典游戏,https://github.com/id-Software)、操作系统、其他编程语言或强制 Firefox 遵守 XDG 基本目录规范的包装程序,因为如果我是管理员的话,这些程序会严格执行我下达的命令!
然而,请不要忘记,即便你可以用 C 编写所有软件,也并不意味着你应该这样做。例如,如果你想创建一个视频游戏,则应该将目光转向 C++。
C++高度向后兼容
为什么我会在这里引出 C++?因为 C++ 是当今使用最广泛的语言之一,而且相信你也经常遇到它。
与其他兼容 C 的编程语言相反,C++ 是 C 的直接后代,而且 C++ 委员会竭尽全力保持与 C 的兼容性(达到复制粘贴即可使用的程度),在大多数情况下,你可以把 C 当成 C++ 一样编译。
但请不要误会,C++ 绝对不是 C 的超集,C 代码不可以与 C++ 一起使用,而且好的 C 代码不一定是好的 C++ 代码。举个例子:
int* x = malloc(10 * sizeof(*x));
这在 C 语言中是正确的方法,但是在 C++ 中,malloc() 之前应该有 (int*),这样才能正常工作,而且你应该使用 new int[10]。
尽管在大多数情况下,你可以在 C++ 项目中安全地使用 C 库。
前面列举的 C 库不仅可以使用,而且人们经常以这种方式使用。例如,我自己在编写十六进制编辑器Bym的时候就在 C++ 代码中使用了 ncurses。
在 extern “C” 链接说明符的助力下,就连使用 C 编译器编译的库也可以与C++ 兼容。
美中不足
C 语言是在B语言的基础上于1972年创建的,因此多年来,C 吸收了一些古怪的东西(字符串标题中定义的 memcpy()!),有些功能已过时,有些已被弃用,C 保留了这些功能只是为了与旧代码兼容。
初学者很可能需要花费大量的时间来追查由于内存损坏而引发的奇怪行为,结果只弄得一头雾水,极大地打击程序员的信心。C 中几乎没有机制可以阻止程序员搬起石头砸自己的脚。
此外,我们需要了解学习 C 不是计算机科学的入门。任何一门编程语言都不是计算机科学入门。你需要经过正规的学习才能对这片广阔领域有真正的了解。即便无法接受大学的正规教育,也可以通过在线教育进行学习。
免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!