原文:https://www.infoworld.com/article/3402023/why-the-c-programming-language-still-rules.html
By Serdar Yegulalp
译文:参考谷歌机翻
前言
没有技术可以坚持50年,除非它的工作比大多数其他任何东西都要好 - 尤其是计算机技术。自1972年以来,C编程语言一直活跃起来,它仍然是我们软件定义世界的基本构建块之一。
但有时一种技术仍然存在,因为人们只是没有取代它。在过去的几十年里,出现了许多其他语言 - 其中一些明确地设计用于挑战C的主导地位,有些语言相当受欢迎,也开始影响C的地位。
编程语言研究和软件开发实践都暗示了如何以比C语言更好的方式做事。但经过数十年的研究和开发,C语言仍然地位稳固。很少有其他语言能够在性能,裸机兼容性或通用性等方面击败它。不过,在2018年,C与流行语言竞争的对比如何,还是值得一看的。
C vs. C ++
C与Java
C vs. C#和.Net
C vs. Go
C vs. Rust
C与Python
C vs. C ++
当然,C最常与C ++进行比较,正如名称本身所指出的那样,C语言被创建为C语言的扩展.C ++和C之间的差异可以表征为广泛或过度,具体取决于您的要求。
虽然C ++的语法和方法仍然像C一样,但C ++提供了许多在C中本身不可用的真正有用的功能:命名空间,模板,异常,自动内存管理等等。需要顶级性能数据库,机器学习系统的项目经常使用这些功能用C ++编写,以便从系统中榨取每一滴性能。
此外,C ++继续比C更积极地扩展。即将推出的C ++ 20为表格带来了更多,包括模块,协同程序,同步库和概念,使模板更易于使用。 C标准的最新版本增加了很少,并侧重于保持向后兼容性。
事实上,C ++中的所有优点也可以作为缺点。大的。您使用的C ++功能越多,引入的复杂性就越高,驯服结果就越困难。将自己局限于C ++子集的开发人员可以避免许多最严重的陷阱和过度行为。但是一些商店想要一起防范C ++的复杂性。坚持使用C迫使开发人员将自己局限于该子集。例如,Linux内核开发团队避开了C ++。
通过C ++选择C是一种方式,对于您和任何维护代码的开发人员 - 通过采用强制简约主义来避免与C ++过度纠缠在一起。当然,C ++拥有丰富的高级功能,这是有充分理由的。但如果极简主义更适合当前和未来的项目 - 以及项目团队 - 那么C更有意义。
C与Java
几十年后,Java仍然是企业软件开发的主要内容 - 并且一般都是开发的主要内容。许多最重要的企业软件项目都是用Java编写的 - 包括绝大多数Apache Software Foundation项目 - 而Java仍然是开发具有企业级需求的新项目的可行语言。
Java语法从C和C ++中借鉴了很多东西。但是,与C不同,Java默认情况下不会编译为本机代码。相反,Java运行时环境,JVM,JIT(实时)编译Java代码以在目标环境中运行。在适当的情况下,JITted Java代码可以接近甚至超过C的性能。
Java背后的“一次编写,随处运行”的理念也允许Java程序在目标架构上进行相对较少的调整。相比之下,虽然C已被移植到许多架构中,但任何给定的C程序仍可能需要定制才能在Windows与Linux之间正常运行。
这种可移植性和强大性能的结合,以及庞大的软件库和框架生态系统,使Java成为构建企业应用程序的首选语言和运行时。
Java缺乏C的地方是Java从未打算竞争的领域:靠近金属运行,或直接使用硬件。 C代码被编译成机器代码,由程序直接执行。 Java被编译成字节码,这是JVM解释器随后转换为机器代码的中间代码。此外,尽管Java的自动内存管理在大多数情况下都是一种祝福,但C更适合于必须充分利用有限内存资源的程序。
也就是说,在某些方面,Java在速度方面可以接近于C. JVM的JIT引擎在运行时根据程序行为优化例程,允许进行许多类型的优化,而这些优化是在未提前编译的C中无法实现的。虽然Java运行时自动执行内存管理,但一些较新的应用程序可以解决这个问题。例如,Apache Spark部分地通过使用绕过JVM的自定义内存管理代码来优化内存中处理。
C vs. C#和.Net
在推出近二十年后,C#和.Net Framework仍然是企业软件世界的主要部分。有人说C#和.Net是微软对Java的响应 - 一个托管代码编译器系统和通用运行时 - C和Java之间的许多比较也支持C和C#/ .Net。
与Java(以及某种程度上的Python)一样,.Net提供跨各种平台的可移植性和庞大的集成软件生态系统。考虑到.Net世界中有多少面向企业的开发,这些都是不小的优势。当您使用C#或任何其他.Net语言开发程序时,您可以使用为.Net运行时编写的大量工具和库。
另一个类似Java的.NET优势是JIT优化。 C#和.Net程序可以按照C语言提前编译,但它们主要由.Net运行时进行即时编译,并使用运行时信息进行优化。 JIT编译允许对无法在C中执行的正在运行的.Net程序进行各种就地优化。
与C一样,C#和.Net提供了各种直接访问内存的机制。堆栈,堆栈和非托管系统内存都可以通过.Net API和对象访问。开发人员可以使用.Net中的不安全模式来实现更高的性能。
但这些都不是免费的。管理对象和不安全对象不能被任意交换,并且它们之间的编组会带来性能成本。因此,最大化.Net应用程序的性能意味着将托管和非托管对象之间的移动保持在最低限度。
如果您无法支付托管与非托管内存的罚款,或者.Net运行时对于目标环境(例如,内核空间)来说是一个糟糕的选择,或者可能根本不可用,那么C就是你的需要。与C#和.Net不同,C默认解锁直接内存访问。
C vs. Go
Go语法很大程度上归功于C-curly大括号作为分隔符,语句以分号结束,等等。精通C的开发人员通常可以毫不费力地直接进入Go,甚至可以考虑新的Go功能,如命名空间和包管理。
可读代码是Go的指导设计目标之一:让开发人员可以轻松掌握任何Go项目,并在短时间内熟练掌握代码库。 C代码库可能很难理解,因为它们很容易变成鼠标的嵌套和特定于项目和给定团队的#ifdef。 Go的语法及其内置的代码格式和项目管理工具旨在避免这些类型的制度问题。
Go还提供了诸如goroutines和channel之类的附加功能,用于处理并发性和组件之间的消息传递的语言级工具。 C需要手动滚动或由外部库提供这些东西,但Go提供了开箱即用的功能,使得构建需要它的软件变得更加容易。
Go的不同之处在于,内存管理方面的内容与C大不相同。默认情况下,Go对象会自动管理并进行垃圾回收。对于大多数编程工作,这非常方便。但这也意味着任何需要确定性处理内存的程序都会更难编写。
Go确实包含了用于绕过Go的某些类型处理安全性的不安全包,例如使用Pointer类型读取和写入任意内存。但不安全的是警告说用它编写的程序“可能是不可移植的,并且不受Go 1兼容性指南的保护。”
Go非常适合构建命令行实用程序和网络服务等程序,因为它们很少需要这种细粒度的操作。但是,最好在C中创建低级设备驱动程序,内核空间操作系统组件以及其他需要严格控制内存布局和管理的任务。
C vs. Rust
在某些方面,Rust是对C和C ++创建的内存管理难题的回应,也是对这些语言的许多其他缺点的回应。 Rust编译为本机机器代码,因此就性能而言,它被认为与C相当。但默认情况下,内存安全是Rust的主要卖点。
Rust的语法和编译规则可帮助开发人员避免常见的内存管理错误。如果程序有一个跨越Rust语法的内存管理问题,它就不会编译。这种语言的新手,特别是来自C语言,为这些错误提供了充足的空间,他们在Rust教育的第一阶段学习如何安抚编译器。但Rust的支持者认为,这种近期的痛苦有一个长期的回报:更安全的代码不会牺牲速度。
Rust还通过其工具改进了C语言。默认情况下,项目和组件管理是Rust提供的工具链的一部分,与Go相同。有一种默认的,推荐的方法来管理包,组织项目文件夹,以及处理C中最多的其他许多事情,每个项目和团队以不同的方式处理它们。
然而,在Rust中被吹捧为优势的东西对于C开发者来说似乎并不像。 Rust的编译时安全功能无法禁用,因此即使是最琐碎的Rust程序也必须符合Rust的内存安全限制。默认情况下,C可能不太安全,但在必要时它更灵活,更宽容。
另一个可能的缺点是Rust语言的大小。即使考虑到标准库,C的功能也相对较少。 Rust功能集非常庞大并且还在不断增长。与C ++一样,较大的Rust功能集意味着更强大的功能,但也更复杂。 C是一种较小的语言,但更容易在心理上进行建模,因此可能更适合Rust那些矫枉过正的项目。
C与Python
这些天,每当谈论软件开发时,Python似乎总是进入对话。毕竟,Python是“所有东西的第二佳语言”,毫无疑问是最通用的语言之一,拥有数千个第三方库。
Python强调的是什么,以及它与C最不同的地方,是有利于开发速度而不是执行速度。一个可能需要一个小时才能用另一种语言组装起来的程序 - 比如C-可能会在几分钟内用Python组装。另一方面,该程序可能需要几秒钟才能在C中执行,但需要一分钟才能在Python中运行。 (一个很好的经验法则:Python程序通常比它们的C语言程序运行速度慢一个数量级。)但是对于现代硬件上的许多工作,Python足够快,而且这对它的应用至关重要。
另一个主要区别是内存管理。 Python程序完全由Python运行时进行内存管理,因此开发人员不必担心分配和释放内存的细节。但同样,开发人员的轻松也是以运行时性能为代价的。编写C程序需要严格关注内存管理,但生成的程序通常是纯机器速度的黄金标准。
但是,在皮肤下,Python和C共享一个深层连接:参考Python运行时用C语言编写。这允许Python程序包装用C和C ++编写的库。第三方库的Python生态系统的重要组块,例如机器学习,其核心是C代码。
如果开发速度比执行速度更重要,并且如果程序的大多数高性能部分可以被隔离到独立组件中(而不是遍布整个代码),那么纯Python或Python和C库的混合使得比单独的C更好的选择。否则,C仍然是主导地位。
现在的硬件速度已经发展很快了,而且将来会更快,所以效率不是问题,能先实现最重要,python会慢慢流行起来的。