是什么让C在OOP时代如此受欢迎?[关闭]


91

我用C和C ++编写了大量代码,但是没想到C是第二大流行语言,仅次于Java。

TIOBE编程社区索引

我很好奇为什么在这个OOP时代,C仍然如此流行?请注意,在前5种流行的编程语言中,有4种是“现代”的,面向对象的语言。

现在,我同意您可以在C中使用OOP,但这有点痛苦和不雅(至少与我猜想的C ++相比)。那么,是什么使C如此受欢迎?是效率吗?低级 绝大多数已经存在的库或其他库?


18
视频游戏,嵌入式系统,硬件编程(固件),操作系统等

25
请注意,您只能得到自己要衡量的内容-对于TIOBE,这是+"<language> programming"流行搜索引擎上的点击数。博客文章“为什么没人再进行C编程了”在该索引中计入了C。哎呀,即使这个问题也可能在Google收到后立即解决。

40
OOP的年龄?这是一个非常大胆的声明。
Mahmoud Hossam 2012年

57
您有一种错觉,那就是OOP是万灵药,您应该很快就失去它,OOP没有什么特别或“好”,它只是许多代码组织策略之一。
雷诺斯

23
@DeadMG:锅,见水壶。TIOBE的数据可能并不可靠,但是您关于“它不受欢迎”的秃顶断言没有任何来源或引证。如果您要质疑问题背后的假设,请至少提供一些证据来支持它。
Daniel Pryden 2012年

Answers:


143

造成这种情况的一些因素:

  • C无处不在。无论使用哪种平台,都可以使用C。
  • C是便携式的。编写一段干净的C,然后在其他平台上进行最少的修改即可编译-有时甚至可以直接使用。
  • C已经存在了一段时间。在UNIX征服世界的时代,C(首选的UNIX编程语言)在其世界中享有统治地位,并成为编程世界的通用语言。可以期望任何认真的程序员至少对C块有所了解。大多数其他语言都不能这样说。
  • 对于UNIX和UNIX风格的系统,C仍然是默认语言。如果您希望图书馆在开源领域取得成功,则需要充分理由使用C。这部分是由于传统,更是因为C是您可以放心地假定所有类似UNIX的语言都支持的语言。系统。用C编写库意味着您可以最小化依赖关系。
  • C很简单。它缺乏复杂的OOP或功能性语言的表达能力,但其简单性意味着可以快速上手。
  • C是通用的。它适用于嵌入式系统,设备驱动程序,OS内核,小型命令行实用程序,大型桌面应用程序,DBMS,实现其他编程语言以及您能想到的几乎所有其他功能。
  • C很快。大多数C实现直接编译为机器代码,并且程序员对机器级别的操作具有完全的控制权。没有解释器,没有JIT编译器,没有VM或运行时-只是代码,编译器,链接器和裸机。
  • C是“免费的”(从啤酒和言语角度而言)。没有一家拥有和控制该标准的公司,有几种实现可供选择,使用C没有版权,专利或商标问题,并且一些最佳实现是开源的。
  • C有很大的发展动力。该语言已经流行了几十年,因此,有大量的应用程序,库,工具以及最重要的社区来支持该语言。
  • C已经成熟。引入重大更改的最后一个标准是C99,并且大多数与以前的标准向后兼容。与更新的语言(例如Python)不同,您不必担心很快就会发生更改。
  • C是兼容的。大多数语言都具有与C对话的绑定。这意味着人们可以使用标准的调用约定在C中开发一个库,并确信几乎任何其他语言都可以链接到该库。仅列举几种广泛使用的流行语言:C#,Java,Perl,Python,PHP都可以轻松链接到C库。
  • C语言很强大:如果语言不能执行任何操作,则所有流行的编译器都允许嵌入汇编程序代码,该代码可以执行硬件可以执行的任何操作。通过与上述有关兼容性的观点进行传递性结合,这意味着C可以充当高级语言与程序集的“裸机”之间的联络人。

9
我认为并非所有论点都是正确的。1)C无处不在。C ++和C一样普遍,因为存在C ++到C的编译器。2)C是便携式的。与C ++相同。3)。C已经存在了一段时间。与C ++相同。4)。C是通用的。与C ++相同。5)C快。与C ++相同。6)。C是“免费的”。与C ++相同。7)。C有很大的发展动力。再次与C ++相同。8)C已经成熟。与C ++相同。因此,您实际上不回答问题。
康斯坦丁·索洛玛托夫2012年

19
C11是最新标准,而不是C99。并不是每个人都使用'89确实重要。
Pubby 2012年

53
@KonstantinSolomatov:如果您正在编写将被其他人使用的库,请帮个忙,用C而不是C ++编写。如果不能这样做,至少要编写一个C API。 宇宙中的所有内容都可以以某种方式链接到C代码,通常只需很少的精力。相反,尝试从其他C ++代码调用C ++代码时,经常会遇到主要的ABI问题,更不用说从其他语言中调用了。
丹尼尔·普里登

37
@KonstantinSolomatov-需要C ++到C编译器的事实证明C是无处不在的。
确实是2012年

11
@KonstantinSolomatov:请不要再认为C是C ++。C没有闭包。C的某些扩展确实可以(例如,由gcc系列编译器实现的扩展)而C 本身却不(例如,它不在原始的K&R规范或任何最终的C标准中)。
Donal Fellows 2012年

88

我一直倾向于将C的普及归咎于对通用汇编语言的需求。它在机器级别的特殊性,标准化和极高的可移植性的结合使C可以充当事实上的通用汇编语言,因此我怀疑C的作用将无限期地继续下去。

我应该提到,当OOP作为一种“最终模型”出现在编程课程中时,我总是感到有些惊讶,这是良好编程的唯一可能终点。像编程的许多其他方面一样,OOP的价值是许多竞争因素之间的折衷,包括人脑如何组织信息,社会团体如何长期支持软件,以及在面向对象编程的情况下,某些深层方面宇宙本身是如何工作的。

最后一点值得一提。如果您对物理级的探索感兴趣,请继续阅读,以了解某些编程风格为何存在,它们如何协同工作以及随着我们对此类概念的进一步扩展,世界未来的发展方向...

物理学中的物体是随时间保持可识别的连贯性的任何事物。这样一来,像我们这样的简单生物就可以只用少量的碎片就可以代表物体,而又不会严重危害我们的生存。但是,从广义上讲,要使这种简化变得容易和普遍,您必须要做的事情很多。作为人类,我们不会考虑太多,因为坦率地说,如果事实并非如此,我们就不会在这里。

听起来太抽象了?真的不是。例如,试想一下,如果您遇到的不是快速行驶的等离子场,而是瞬间移动的物质以大范围的速度运动,那么试图在通往朋友家的道路上行驶。这样的情况可能会相当深入地挖掘社交机会,是吗?我们需要对象,我们对象,对象的存在为我们提供了极大且至关重要的简化周围环境的水平。

因此,让我们将所有这些都带回软件中。在编程方面,现实世界中的对象必须对对象说些什么?

嗯,一方面,这意味着在软件中定义“好”对象的真正应该是您正在处理的数据类型是否随时间支持可识别的持久性的想法。

根据定义,最简单的OOP形式很容易识别。它们只是通过使用已经由某些“真实的,真实的物理对象(例如人,房子或汽车)”“附加”或定义的数据来解决问题的对象。即使在今天,这仍然经常是人们在软件课程中获得的对象的唯一定义。这太糟糕了,因为即使是琐碎的面向对象程序也需要比这更广泛的定义。

第二个也是更有趣的对象类别包括永生化的现实世界事件。所谓“永生”,是指至少短暂地存在于现实世界中的一个定义明确的实体或集合中,然后又分散并不再作为具有物理意义的集合而存在的事物。座谈会就是一个很好的例子:座谈会作为一个定义明确的场所和人物集合存在了很短时间。但是,a,即使是最好的会议也必须结束,并且组成这些会议的各个部分都转到了其他活动上。

但是,通过使用计算机和网络,我们可以通过捕获和维护作为软件对象的内存来使这样的短暂研讨会看起来像一个长期对象。我们使用计算机和数据库进行的许多操作都可以使这种瞬态事件永生化,在这种情况下,我们实际上试图通过捕获和扩展物理上不可能存在的方式来丰富我们的真实宇宙。例如,您最近看过真正的Pandora吗?对现实世界作品的这种捕获和扩展有助于以非凡的方式丰富和扩展我们自己的生活,经济和选择。对我来说,这是面向对象编程的中心地带,它曾经并且一直在产生着最显着的影响。

OOP的最后一个类别由与外部事件没有密切联系的对象组成,而是基础结构需要使用来自现实世界的永生物体来支持我们对现实的不断扩展。在这里,您可以一路下降到计算机的(半)金属,创建持久的现实碎片,就像现实世界中的化学元素一样,可以快速有趣地组合起来以构建新的内部世界。移动计算帮助促进了这种高度重组的方法的发展,这种方法在许多方面再次模仿了物理世界的重组特征。这也很困难:随着时间的流逝,看起来似乎不错的选择可能证明是一个出乎意料的坏选择,通常是因为它最终阻碍了多样性和扩展而不是支持它。

这最后一类也指出使用编程只是一个模型的风险,因为就像现实世界中,编程世界也需要一个过程与相对不变的对象很好地对应。地球充满了物体,但是太阳充满了高度动态的能量流,最终需要这些能量流来“驱动”低能量地球上的物体和活动。同样,在创建计算世界时,有些情况下您必须处理流程和转换以及快速变化的上下文,尽管它们本身并不是很像对象,但是对于启用更高级别使用的更简单,更人性化的对象绝对至关重要。并非偶然的是,在内核级别完成的许多编程都不明显是对象式的,或者它往往严重依赖于像C这样的面向处理的语言。这些是更深层次的领域,可以补充我们在计算机生成的世界中看到的引人入胜的多样性。

OOP可能会出错的另一个领域是过于关注对象概念。

现实世界中的物体,尤其是生命物体,具有以惊人和复杂的方式与环境互动的绝对惊人的能力。相互看待,进行兼容性和完整性检查的可组合窗口小部件,甚至可能发现一些新的交互方式比我们倾向于的简单框架和简单继承方案更接近现实世界中对象的生物学概念。在代码级别专注于(通常是必要的!)。这是网络世界中对象增长的领域之一,更像是“类似代理”的方法,即使在编程本身内,对环境的反应也是正常的。

对于我对OOP的“批评”,还有很多!不过,尽管如此,我希望我已经指出了为什么创建一个更加丰富的网络世界意味着包含各种编程风格,而不是假设只需要一个。我的感觉是,无论我们现在做什么工作多么平凡,真正有趣的东西还没有出现!


18
我敢肯定,在“仅在您对物理级探索感兴趣的情况下,请进一步阅读”部分中有很多人退出。我很高兴没有。这种想法动摇了我们理解的基础,也许是我们取得显着进步的唯一途径。感谢您的阅读。
马特·埃施

@ Raynos,$ MattEsch,感谢你们两个的客气话,我很高兴您发现它很有趣!
特里·布林格

1
注册该站点只是为了能够投票-这个深思熟虑的宏伟答案。=)
sgorozco,

2
符合您的想法,我从事编程已经有一段时间了,并成为了O​​OP狂热者,因为当我采用它时,我真的看到自己的编码技能得到了极大的提高。但是经验告诉我,强迫一切变成对象确实是有害的。我现在不喜欢对象到关系的映射工具(有点混乱)或完整的对象图序列化方案,与简单的二进制协议相比,该方案消耗了1000%的带宽,而该简单的二进制协议仅通过有线方式发送需要的适当数量的二进制数据。此时此刻。感谢您的阅读。
sgorozco

2
这个答案也是为什么我们仍然需要SQL的答案!
HLGEM 2013年

25

首先,尽管关于此的任何教条都已普及,但您并不需要所有的OOP。与Java不同,C允许使用函数指针甚至闭包,这为函数式编程打开了大门,并解决了OOP句柄的相当一部分问题,因为它提供了依赖注入的方法。也谨慎使用宏实际上可以创造一些非常好的事情,因为sglib证明。

以一种奇怪的方式,人们可能会将C视为Java和C ++之间的良好折衷。请注意,我并不是说C两者都是混合的。但是与Java相比,它是一种功能强大的语言,而与C ++相比,它具有可管理的复杂性。

这是一门古老的语言,已经变得可靠和一致,而实际上并没有变得更加复杂。除此之外,它拥有巨大的生态系统,并且可以随处运行。


11
函数式编程很棒,对此没有异议。但是C对于函数式编程来说是一种相当糟糕的语言。闭包/块是不可移植的黑客,并且语法丑陋(我敢打赌,还有陷阱)。即使忽略所有这些,您仍然必须关心内存管理。C是一门有用的语言,但是与任何一种语言一样,如果您滥用它来使用不是专门为您准备的范式,那么您的生活就会变得更加艰难。您也可以在Java中模拟函数式编程(请参阅Guava),但这也不好。

7
如果没有垃圾收集器,就很难以功能样式进行编程。
康斯坦丁·索洛玛托夫2012年

@KonstantinSolomatov:首先,这是非常主观的。其次,如果需要,可以将垃圾回收添加到C中。
back2dos 2012年

如果您想在Java和C ++之间妥协,请尝试Obj-C :)绝对每个C / C ++程序员都应该尝试一下。
苏珊(Sulthan)2012年

21

C具有ABI(应用程序二进制接口),C ++没有。在某些情况下,这使C比C ++更有用。如果我要编写一个库并且能够将二进制文件运送给其他人使用,那么C ++是完成这项工作的错误工具。如果我要编写将被其他语言再次使用的库,C是完成这项工作的正确工具。我从未听说过不支持C的FFI(外函数接口)的语言,另一方面,如果使用不同的编译器,则C ++不能与用C ++编写的库一起使用。

基本上,它可以归结为C,以填补C ++不适合的角色。


2
嗯.. C,番茄和奶酪卷!
DeadMG 2012年

3
好吧,C ++确实有一个ABI。只是C ABI坚如磐石,而C ++却经常改变。再加上很多C ++模板已编译到正在使用的应用程序中,因此您无法对其进行更新。当所有功能都隐藏在函数调用后时,可以修复库并使应用程序正常运行。
2013年

12

与C ++或Java之类的语言相比,使用C的一个优势是,引擎盖下没有发生很多魔术。分配项目时不运行构造函数,而对象超出范围时则不运行析构函数。没有名称修饰,也没有vtables。性能更容易预测;您不必担心垃圾收集器会中断例程并取消其时间安排。

构造函数,析构函数,名称修饰,vtables,垃圾回收器等可以减轻您编写的代码中的某些复杂性,但是这种复杂性成为语言本身的一部分,您几乎无法控制它。您可能会花费更长的构建时间(烦人的但可以容忍的),更大的运行时内存占用空间(可能可以容忍或可能不能容忍)或性能降低。在C你可以削减掉一些复杂的,直到你离开你的功能需要

例如,C ++ string数据类型比C样式的字符串更容易处理数光年,但这是相当重量的代码,给图像大小增加了很多。我很少见过有人string在任何一个程序中都充分利用的功能。C风格的字符串虽然较难使用,但对运行时间和图像大小的影响却较小,因此,对于特定问题,它可能更具吸引力。


2
运行时间的惩罚是胡说八道。C字符串(以Null结尾)比C ++字符串效率低得多。此外,串类可以一样紧凑,C,只要你不拖整个std英寸
Pubby

1
string如果您静态链接CRT ,不会删除未使用的未使用功能的工具链是不值得的。
Billy ONeal 2012年

10
傻的事情是,我有一个图书馆,工作std::string不复杂的不够。如果您真的很认真地考虑字符串,无论是在性能还是功能上,您都可以重新使用C并自己重新做一遍,尽管不能char*肯定地使用老式的s。(即使您期望它们很复杂,字符串也非常复杂。)
Donal Fellows 2012年

1
@DonalFellow有趣。这正是C标准总是放弃字符串和哈希表之类的原因的原因,有时它们的缺失会激怒我。
工程师

@ArcaneEngineer:C中基本缺失的数据类型是“ T []切片”类型,它将组合T *和size_t,可以像数组一样被索引,可以分解为T *,并且可以隐式转换为任何T [n]类型(其大小由编译器自动提供)。这种类型可以在很多情况下允许进行自动边界检查,而在其他情况下则不可能进行自动边界检查,同​​时使许多代码更清晰易读。
超级猫

11

嵌入式系统和驱动程序通常使用C进行编程。此外,还有大量仍在维护和扩展中的遗留C系统。


2
是的,C在所有程序上运行。而且它是一种非常容易学习的语言(与c ++相比)。
本杰明·B

10

在气动锤(气锤)时代流行手动锤的原因是:C仍然是某些工作的正确工具。


6

简单,一致和精确。

这很简单-您不需要复杂的开发环境,庞大的库或虚拟机。

这是一致的-十年前编写的大多数C都可以在今天编译。

精度-它使您可以深入了解计算机的级别,并根据需要知道内存位置。这对于性能和嵌入式硬件非常有用。

它并不能解决所有问题,还是有用的工具。


5
更好的是,十年前编译的代码很有可能今天执行
Donal Fellows

@DonalFellows:而且,对于使用插件的应用程序而言,今天的应用程序很有可能会编写,构建和发布(以可执行形式)的应用程序将能够使用通过构建工具编译的插件,而这些构建工具甚至还没有被使用过。设计尚未。
超级猫

6

我从另一个答案中引用了两点,因为它们准确地说明了我仍不时使用C的原因(尽管这不是我选择的主要语言):

  • C很简单。它缺乏复杂的OOP或功能性语言的表达能力,但其简单性意味着可以快速上手。
  • C已经成熟。引入重大更改的最后一个标准是C99,并且大多数与以前的标准向后兼容。与更新的语言(例如Python)不同,您不必担心很快就会发生更改。

我认为这是真的。我在晚班学习了C:它很简单,关键字和构造很少,大部分工作是由图书馆完成的。然后我几年没有使用C了。在2002年左右,我需要快速实现算法,我安装了C编译器并实现了它。我知道这门语言,我知道这有什么用处,也有什么用处(我永远不会用C语言实现Web应用程序!),当我需要它时,它就在那里。没什么好奇怪的

使用C ++,我有不同的经历。我是在1995年左右学到的,这意味着从命令式到OOP的重大转变。大!直到1999年,我才将其用于多个项目。几年来,我一直没有使用C ++,当我再次使用它时(2008年),我发现该语言中已经有很多新功能,甚至还有更多计划(同时在C ++中引入) 11)。我感到必须再次学习该语言。

作为开发人员,我更喜欢成熟,稳定的语言。我喜欢学习一种语言,了解它的设计原理,有什么用,并在我认为这是完成工作的正确工具时使用它。我还喜欢学习不同的语言,并选择适合我需要的语言(C,C ++,Java,Scala,Haskell等)。我不喜欢的是必须一次又一次地学习相同的语言,因为它会不断发展,并且永远不会成熟。

恕我直言,一种编程语言应具有清晰,连贯且稳定的设计。我喜欢尼克劳斯·沃思(Niklaus Wirth)这样的设计师的方法:每当他感到需要另一种语言时,便设计了一种新语言(Pascal,Modula-2,Modula-3,Oberon)。我不喜欢每隔5到10年就会发生重大变化的语言:它们就像移动的目标,而且我从来不觉得不值得花时间来深入学习它们,因为我现在正在学习的版本可能会在几个版本中过时了几年了。

从这个意义上讲,C是IMO的赢家:它对某些应用程序有利,而对其他应用程序则不太合适,但是它具有简单且相对稳定的优点。


4

我很惊讶没有人提到更糟。目前已经有20多年的历史了,但仍然值得一读。尽管有时会有些嘲讽,但它很好地概述了权宜之计通常如何以及为何胜过理想的原因,并使用C(与LISP相对立)作为其中心示例之一。


我将其归类为“更糟但更好”的类别:英语,PHP,Windows。麦当劳。尽管我仍然羡慕/喜欢西班牙语,Python,Linux和Artisan French Cooking;尽可能(如果不是通常的话)。
ThorSummoner 2015年


0

没有。TIOBE是毫无价值的指数。如果您实际查看它们的度量,那绝对是一个绝对的猜测。


10
TIOBE一文不值的事实并不意味着C不受欢迎
Raynos 2012年

但是,它确实的确击败了OP中提出的论点-C很流行,因此它必须有一定用途。
DeadMG 2012年

2
更好地衡量C的受欢迎程度的是,几乎每个平台都有一个C编译器
Raynos

@Raynos:根本不是衡量。唯一的意思是它很容易实现。它没有说明有多少人使用它,或者为什么。
DeadMG 2012年

2
不完全是,我很高兴接受相反的观点。您的一句话答案似乎没有多大用处,并且您对自己的回答充满争议。
mattnz 2012年

0

许多旧版软件

许多公司无法更改,立即将所有代码转换为C ++或类似代码。

许多公司无力更改其代码。

许多公司可以负担得起更改其代码的费用,但不在乎或“便宜”。

许多公司正在迁移中,但尚未完成。

隐藏的物体方向

(非面向对象的)C源代码,被设计为面向对象的C源代码,使用“对象定向”建模并使用“纯C”编码的应用程序,或从“ C ++”或其他OO程序转换的工具。郎成C.

我听说有些电子游戏就是这样做的。一些跨平台工具,以及用于GNome Linux OS发行版的GTK(GObject,GLibrary)可视界面库。


3
这个答案的后半部分需要去混淆。
aramis 2012年

@aramis。第二部分的意思是:许多代码似乎直接用“ C”编写,实际上用其他语言,并翻译成“ C”
umlcat 2012年

0

我看到一些回答者回答了为什么C最受欢迎,它存在了很长时间,可以在大多数平台上使用,免费等等。

但是其他语言(例如免费的Pascal)也可以这样说-它是免费的,并且几乎所有平台都支持。

Pascal是在1970年左右发明的,C是在1972年左右发明的,所以我认为Pascal的历史与C差不多。

我个人认为C是最流行的语言,因为那里只有更多开放源代码可供任何人重用。是的,它的级别比Pascal低,因此它已接近汇编语言,但比汇编语言更具可读性。

我认为那里有太多的编程语言。作为程序员,我们必须了解大多数重要的知识,但最后应该没有必要。从构建网站到iOS计算机游戏,都可以使用一种编程语言来完成所有工作。

C似乎是全球语言,但我希望它会像Object Pascal这样。为什么使用对象Pascal,它是一种更具可读性的编程语言,所以OOP代码的确比C更易于重用,并且不易出错(在我看来)。

使用对象Pascal比使用C / C ++更容易管理大型应用程序。

至于自70年代以来一直是一种编程语言,而不是喜欢每5或10年更改一次的语言。随着时间的流逝,技术进步和编程方法得到了改进。如果一种语言每隔几年发生巨大变化,那么它的设计者可能就没有很好地考虑过。但是1970年至2012年将近半个世纪,可以在那时对语言进行更改以结合软件开发中使用的先进技术。

C本身已被多次修订。因此,这并不比其他语言更好。


3
Pascal的一个问题是该语言的“官方”版本遗漏了一些非常必要的功能。相当长一段时间以来,PC和Macintosh都使用了Pascal编译器,它比当时存在的任何C编译器都实用得多,但是这种编译器增加了任何“正式”标准都不支持的语言扩展。我认为,如果要努力制定正式的标准来编纂此类扩展名,Pascal可能会取代这种被称为“ C”的语言的黑手。
2014年

0

因为C有庞大的用户群。是的,这有点让人难以接受,但是当我在StackOverflow上提出有关C的问题时,我几乎立刻就得到了答案。关于Python的相同问题可能要花几个小时才能得到解答。

关于C ++,它的学习更复杂。此外,在尝试了OOP 10年之后,我发现它并不总是有用,而且通常更容易使用过程编程。


您是否比较了C#或Java的SO问题?
蚊蚋

@gnat是C v Python的一个孤立示例(顺便提一下,还有更多问题!)。我没有C#的经验(您是否注意到我没有问C#或Jav的SO问题?)
puk

嘿,我发现StackOverflow上的#python社区几乎总是超级快。尽管如果C社区在回答速度上超过javascript社区,我会感到惊讶。(主要是因为体积)
ThorSummoner 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.