以下为译文:
虽然 C 语言并不是我所学的第一门语言,也不是我的最后一门语言,但是我仍然非常喜欢 C,当需要写程序时,我的第一选择还是 C。同时,我也会关注现代编程语言及其发展趋势,而且我还使用 Rust 编写了自己的业务爱好项目。那么,为什么我没有抛弃 C 而选择其他语言呢?我对于 C++的看法又是如何的呢?
1、为什么说C不是最好的语言?
首先,这个世上没有最好的编程语言。每种语言都有独特的优势以及适用情况,所以尽管你可以在 Excel 中编写光线追踪程序,但最好还是使用其他语言。因此,我们都需要了解编程语言的限制,不要抱怨 Web 服务器不是用 Fortran 编写的,也不要抱怨基本没有任何应用使用 Perl 或 C++作为内部脚本语言。我认为 C 语言不太理想的方面包括以下几点(除了 C 比较老,发展不快之外,当然还与个人的喜好有关)。
其次,有些时候,C 的语言不够明确。比如,*可以是二进制乘法运算符、一元解引用运算符,也可用于声明指针。
再者,有些情况不够安全,例如越界访问数组这种极其常见的错误都没有运行时检查,这一点连 Borland Pascal 都比不了,更不用说更现代的编程语言了(尽管你会为了提高性能关闭这个编译选项)。此外,指针让我们很难保持一切井然有序。再加上一些其他情况,比如调用函数不需要事先声明原型,这样很容易将错误类型的参数传递给函数。
最后,C 的标准库非常有限。有些编程语言甚至拥有开箱即用的 Web 服务器(或者至少有构建 Web 服务器所需的所有模块),但 C 标准库甚至连 Web 服务器的容器也没有。
2、为什么我还是喜欢C?
尽管如此,我还是十分喜欢 C,因为它是一种简单的语言。从某种意义上说很简单,很容易表达自己的想法以及期望。
举个例子,假设两个数组有两个偏移量,其中一个可以为负数,如果使用C语言编写,则可以写成:
arr[off1 + off2]
如果是Rust,则需要写成:
arr[((off1 as isize) + off2) as usize]
通常,C 的循环也比 Rust 的迭代器组合更为简洁(当然 Rust 也允许使用前一种方式,但 linter 并不满意,它会建议你使用迭代器来代替)。类似地,memset()和 memmove()也是功能十分强大的工具。
在大多数情况下,你都可以预见到编译的结果,即对象在内存中的表示方式,以及如何通过不同的方式理解编译后的结果(新版 C 标准中这一点变得更困难,这都要怪 C++,我稍后再详细介绍)。另外,你也很清楚函数调用的结果等等。由于这个原因,C 被称为可移植的汇编语言,所以我非常喜欢 C。
我们拿汽车做个类比,C 语言就像一辆跑车,拥有手动变速箱,可以提供最佳性能,但是如果你不熟悉离合器和挂挡操作,那么变速箱很容易被损坏,甚至可能损坏发动机,当然,油门踩得过大也有可能冲出马路。然而,与自动变速箱相比,这种车辆的发动机能量更大,而且你可以预测性能,还可以炫车技,这些在其他车辆上都是不可能的。
3、这与C++有什么关系?
下面,我们来说一说 C++,其实我不讨厌 C++。我不能否认,与 C 相比, C++ 拥有两个优点:
更好的程序结构:C++ 拥有命名空间和类,而且在某些方面Simula还是很出色的。
拥有 RAII 概念:一个简单的例子就是 C++ 拥有构造函数,可在创建对象时初始化对象;还拥有析构函数,在销毁对象时,做一些清理的工作。这个概念进一步发展,就接近 Rust 的生命周期了。
另一方面,C++ 有两个特征,我非常不喜欢。
首先是这门语言的整体性质。其他编程语言拥有的流行功能最终都会进入 C++。因此,每过几年,C++标准就会添加一些新功能。最终,这门语言就变得有点怪异,没人能够完全掌握,而且许多功能都是抄袭的其他语言。基本上每个人在编写代码的时候,都会选择一个 C++的子集,然后忽略其他功能的存在。另外,我们究竟应该使用哪个 C++版本的功能,并没有一套标准的方法。Rust 在包的范围内提供了版本管理。据我所知,C++也曾尝试过引入“代际”的概念来实现同样的功能,但没有成功。我经常听到有人独自编写 C 编译器,却从来没听说过有人编写 C++编译器。
其次,实际上 C++不仅是多种语言,而且还是一种元语言(即模板)。我了解 C++的创建初衷,也同意它对于与类型无关的代码的处理,比 C 预处理器更好。但实际上,它产生的代码十分可怕,原本是“头文件仅包含声明,实现放在编译好的代码中”,变成了“头文件包含所有项目会用到的代码”。我不喜欢过于冗长的编译时间,但这种方式只能让情况更糟。
最后,我觉得 C++的出现反而给 C 带来了约束以及不良影响。我不是在讨论 C/C++,也不是指 C 与 C++的共通之处,我讨论的是耦合对标准和编译器都有不良影响。一方面,C++建立在 C 之上,从而得到了极大的发展;另一方面,如果 C++中没有 C 遗留下来的大多数功能的话,情况可能会更好(当然,C++曾设法通过淘汰的方式逐步放弃某些 C 功能,但对于旧功能的支持仍然存在)。但是,C++ 24 能够在 C++ 21 的基础之上,发展成为一门独立的编程语言吗?大多数过时的功能都可以抛弃吗?我对此表示怀疑。
|