仍然使用C编程语言吗?


96

我是C#程序员,我的大部分开发工作都是针对网站以及一些Windows应用程序。就C而言,由于没有必要,我已经很长时间没有使用它了。当我的一个朋友说她在学习C#时需要学习C来测试工作时,我感到惊讶。

我认为,只有有人用C进行开发,才会有人学习C进行测试。据我所知,所有与COM和硬件设计有关的开发也都用C ++进行。因此,如果您需要使用C ++,则学习C毫无意义。我也不相信历史意义,那么为什么要花时间和金钱来学习C?

C仍用于任何新软件开发或其他任何形式吗?


46
您见过用于PIC的C ++编译器吗?
SK-logic

195
我是唯一让某人将学习等同于浪费时间和金钱的人感到悲伤的人吗?
杰蒂2011年

37
据我所知,与COM和硬件设计有关的所有开发也都在C ++中完成 ” –对我来说,您实际上并没有进行任何硬件接口设计。
Ed S.

32
人们忘记了,我们都爱C.经常实施的花哨高级语言
大卫·考登

13
@ThomasEding死语?如果您认为C是一种死语言,那么您当然对编程语言的了解非常有限。
JesperE 2013年

Answers:


214

C的优点是它是一种相对较小的语言,这使得实现C编译器变得容易(而C ++编译器是编写的怪物),并且使学习该语言更加容易。另请参见TIOBE索引,根据该索引,C稍早于C ++。

在(IMO)的递减排序顺序中,C仍然用于

  • 嵌入式的东西
    将C编译器移植到小型平台比移植C ++编译器要容易得多。同样,C的拥护者声称C ++“在背后有太多的作为”。但是,IMO就是FUD。

  • 系统编程
    同样,这通常是由于声称“知道编译器在做什么”更容易。但是,许多嵌入式程序将受益于例如模板和其他C ++关键功能。

  • 开源软件不过,
    这主要是一个态度问题:OSS始终偏爱C而不是C ++(而在大多数行业中,情况恰恰相反)。实际上,在Linux上, Torvalds的非理性仇恨可能是最重要的原因。


16
历史比态度更重要。您可能认为的许多“核心”开源程序包最初是在C ++的普及程度不如现在,资源仍然匮乏时开发的。
Blrfl 2011年

65
TIOBE指数是个玩笑。搜索引擎的点击是没有意义的。
DeadMG

29
@Sedate:模板通常导致代码膨胀是一个神话,这是从古代C ++编译器时代来的。现代编译器将折叠相同的模板实例。OTOH,模板允许模板元编程,该模板元编程在编译时而非运行时执行代码,从而减少了生成的代码。而且,它们使程序更安全(无需强制转换),这在嵌入式领域中通常非常重要。C ++专家因抛出模板的愚蠢性而被EC ++专家判处死刑。
2011年

18
@James:您的意思是诸如高效抽象,通用编程和类型安全之类的东西?是的,谁想要那个。
Xeo 2012年

11
@JesperE碰巧的是,自从写这篇文章以来,我已经换了工作,现在我正在为嵌入式设备编程。我们使用的是C ++,当您的硬件,实时性和硬件条件较差且缺乏可靠性时,STL和模板元编程可以为您提供出色的服务。(我们在做发电厂。)是的,您必须知道对于某段代码应该使用a std::vector还是std::mapa,但是您不必自己实现它,而是可以依靠经过良好测试的高性能,提供高抽象度的可靠库实现。
2013年

119

C在资源稀缺的嵌入式硬件编程中经常使用。

Linux内核是用C编写的,因为根据Linus Torvalds的说法,C ++是一种可怕的语言


14
我认为Windows内核的很大一部分也是C。还有许多旧系统。
编码器

14
为了完整起见,Linus确实尝试了内核中的C ++。这不是一个问题,而是一个加号。无论如何,内核开发是一个非常具体的主题,这并不意味着C ++通常不好。
deadalnix

75
根据其他人的说法,莱纳斯的论点太可怕了。
2011年

36
Linus的论点可能有效,也可能无效,但是Linux内核仍然使用纯C编写:-)
Joonas Pulakka 2011年

15
Linus是个混帐。
ubiyubix 2011年

94

我见过的所有现代语言都可能与C交互:

  • C ++
  • 爪哇
  • C#
  • 蟒蛇
  • 哈斯克尔
  • 目标C

与C交互的需要源自:

  • 具有简单ABI的C
  • C存在了很长时间

这意味着由于这些语言可以与C通信,因此它们可以:

  • 利用其库
  • 通过 C 相互通信(例如,Clang用C ++编写,但提供了钩在其C接口上的Python绑定)。

而且我敢打赌,他们所有人都依赖C来运行(除非他们进行了完全汇编?这是可疑的)。

C是编程语言的Lingua Franca,并且是不依赖于特定体系结构(例如汇编语言)的最简单的语言(在ABI方面),要摆脱它,将需要进行重大的改变。


45

在我看来,这是一个非常短视的问题,类似于“我和我的朋友都在听雷鬼音乐。有人真的还在听Rap吗?”。

每种语言都有其用途。不同的语言肯定有其利基。但是问C!我确信每天使用C#的人数要少于C(从在没有人使用C#的商店工作的完全偏见的角度来看)。

快速谷歌看语言的相对流行。
我确信这都不是权威,但是我们可以用它来观察趋势:

http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html
http://langpop.com/

甚至在标签上查看问题的比率:https
//stackoverflow.com/tags

  • C#:209845
  • 其他16个标签
  • C:38790

因此,C是SO上18个最受欢迎的话题(那里还有很多其他语言)。

注意:上面的TIOBE索引已经进行了十多年的不断更新(并且有一些数据可以追溯到三十年前),用于衡量使用每种语言工作的工程师(尽管我不知道它的准确性如何)。在Java / Visual Basic之外的前10种语言中,它反映了我商店里的人们所知道的(尽管由于样本量小得多,所以我们的比率会略有不同)。


1
这个答案使我感到困惑...您继续讲C#,然后显示SO问号,但这些问题与使用C并没有任何实际关系。流行度(尤其是在langpop上,他们使用搜索引擎查询来确定流行度)并不能真正显示语言的现代用法,而只是显示对某种语言的现代搜索。对于搜索,您必须考虑到C在大学中经常用于较低级别的类,这样可以增加查询的数量以及SO的数量。
杰蒂2011年

3
@杰蒂:那就是为什么我明确地说:I am sure none of this is authoritative but we can use it to see trends但是我不同意你的第二句话;C不再是高等学校教授的主要语言(如果那样的话,那么新一批的毕业生就不会那么没用了)。如今,人们倾向于学习Java / C#。此外,Tiobe报告是关于作业而非查询的。
马丁·约克

回顾过去,我似乎在单词选择上很差。我并不是说低级类(开始类),而是系统类(计算机体系结构)是使用C的地方。
2011年

4
SO标签计数通常不定义语言流行度,它只是显示SO用户之间的语言流行度。
Ed S.

4
@Ed S.显然。但是问题不在于受欢迎程度。关于C作为一种语言的存在。SO标签的数量向我们表明,这绝对不是一门废话。C在其他站点上位于前2位的事实并不意味着它是使用频率第一/第二的语言。但是它在前十名中的存在是一个重要的标志,那就是它还没有死。当然,这些都不能证明C仍在积极使用中。
马丁·约克

23

当您的资源不足并且不需要面向对象的功能时,可能需要使用C。

当今使用的许多软件仍然是用C编写的,更不用说硬件驱动程序了。

根据Tiobe索引,C仍然是最常用的语言。


正如tcrosley所建议的那样,您可能想看看这个相关的问题


您也应该检查像C和C ++之间的差异的一些相关的文章这个wiki为一例。


4
哎呀!那就好了。我从未想过“ OOP功能实际上会增加语言的开销”。感谢您阐明这一有效观点。现在,我知道C领先于其他人了
Pankaj Upadhyay

7
@Pankaj C ++通常并不一定会增加运行时间开销,该语言的很多复杂性是“不为不使用的东西付钱”的原则-如果您不使用异常,那么异常就不会放慢速度或增加代码大小。编译器是更大和更复杂的,虽然
马丁贝克特

2
再在嵌入式领域C,也看到了这个问题和答案:programmers.stackexchange.com/questions/84514/...
tcrosley

6
您实际上并不需要 OOP功能,它在某些情况下可以很好地工作。
Ed S.

2
@Jose Faeti:我的老板会同意,因为我的老板是一个经验丰富,理性的人。他不喜欢编程宗教。
Ed S.

20

听起来您好像在试图使自己相信C是无用的,因此可以忽略。让我们分解您的问题:

“我认为只有在C语言中完成开发工作的人才能学习C语言进行测试。”

不,有许多学习C的理由。即使您不知道我仍会避免使用类似的笼统语句,尤其是与循环逻辑结合使用。显然,人们需要知道代码的编写语言,以便能够正确地测试/修复它,但前提是该语言仍然作为给定语言使用,并且对任何语言都适用,而不仅仅是C。

“据我所知,与COM和硬件设计有关的所有开发也都用C ++完成。”

那是不对的。

“因此,如果您需要使用C ++,那么学习C毫无意义。我也不相信历史意义,那么为什么要在学习C上浪费时间和金钱呢?”

这是最可疑的逻辑。首先,历史意义是您应该相信的东西,因为如果您这样做了,您就会知道C是C ++的子集,因此,了解C可以帮助您成为更好的C ++程序员。当然,C对后来出现的大多数语言也有影响,因此好处不止于此。此外,由于C非常重要,因此不能认为C仅具有历史意义。它仍然被广泛使用,因此不能降级为次要位置。您可以辩称这不是每个程序员都需要使用的语言,并且不是一种全面的知识,这是正确的,但是请不要在说您不相信某些东西而不首先检查其真正优点的情况下建立您的论点。


7
C是C ++的子集,这是您的意思吗?。C不是C ++的子集;实际上它们是完全不同的。是的,C ++是C的增强,或者有时被称为带有类和OOP的 C,但是说C是一个子集,则不成立
Pankaj Upadhyay

7
C ++主要是旧版本 C 的超集,从那以后C的发展方向有所不同。这些语言的某些方面在很大程度上是平行的,但其他方面则没有(C ++还有很多其他事情)。
Donal Fellows

我同意为澄清这一事实而投票,并非所有有效的C程序都是有效的C ++程序,即C ++不是C的超集。但是,这是C在决定将其变为C时的方式的超集。正如Donal Fellows所提到的那样。但是,当它不再是真的时,就说它不再是没有意义了。
约书亚树篱,

16

除了嵌入式系统之外,大多数较新的语言都具有某种与C交互的方式。当编写一个想要轻松使用所有这些语言的库时,C是一个显而易见的选择。C ++虽然还可以与某些语言(例如Python(仅适用于CPython)进行接口),但由于C ++的某些功能(尤其是名称修改,但模板无济于事),它无法与多种语言进行接口。C ABI是最简单的接口之一(我知道您可以编写C ++并在接口中使用extern“ C”。我不在乎)。

它还具有C和C ++实际上是系统编程的最佳语言的好处,并且C编译时间快得多。C ++编译时间显然是我使用过的所有语言中最差的。

现在,尽管有其他语言想要成为流行的系统语言(尤其是D),但绝大多数软件都是用C / C ++编写的。像D这样的语言需要有人在C库周围创建包装器,而不是直接使用它(就像从C ++中那样)。


D可以像C ++一样直接调用C代码。函数原型所需的一切(同样,就像C ++)。您只用extern(C)D 编写,而用C ++编写extern "C"
Peter Alexander

@Peter Alexander我知道D中的extern(C)。这就是我说包装文件时所指的内容。您不能直接包含C头文件(如果C头文件使用extern“ C”并具有#ifdef __cplusplus块,则可以在C ++中完成此操作)。在使用extern(C)之间还有其他不兼容性(特别是字符串的处理方式。据我所知,它们在D中没有空终止符。因此,在将数组传递给C时必须专门更改数组)。
jsternberg 2011年

11

请访问langpop.com,尤其是Freshmeat和Google Code中的图表。它表明C仍然遥遥领先。

C在仍然需要接近金属(即嵌入式系统)和性能要求高的应用程序的系统上仍然很流行。


4
不要打开这个URL!该网站已不存在,并且URL重定向到一些令人讨厌的垃圾网页。
Nikolay Suvandzhiev

11

我几乎每天都在为iPad / iPhone开发它。许多库都是用C编写的,没有等效的Objective-C。因此,是的,它仍在使用,并且被市场上最新的设备之一使用。

使用C,您可以对许多嵌入式系统进行编程,而且体积小巧,方便,并且可能存在很多年(也就是说,您既不会浪费时间,也不会花时间学习它)


2
“ Objective-C还很年轻”,实际上是从1980年代中期开始,大约和C ++一样古老。不过,大多数使用它的人直到2007年才发现它。

没错,我想说的基本上是,有很多C库在iOS的Objective-C中没有等效的库。的确,语言本身根本还不年轻(与Wiki核对)。感谢您指出了这一点。
瓦伦丁·拉杜

7

通常对于嵌入式系统C仍被广泛使用。

这个问题给出了另一个例子。

TIOBE指数,它试图通过分类语言流行 / 用法,始终把下在第一个地方。


第二名(仅次于Java)。
马丁·约克

7
有趣的是,在过去的十年中,C ++和Java的流行率似乎都在下降,而C或多或少地保持静态。
Paul R

7

可移植性。

列出您认为将运行C代码的每个系统的清单,然后列出您喜欢的其他每种语言的清单。

如果您提出的答案与我相同,那么结论是肯定的。


5

好吧,我认为C是最强大的语言,原因如下:

1)在第一个C处,这是一种系统语言(这意味着它可用于以最少的运行时间或没有运行时间来进行低级编程)。

2)生成的应用程序的速度。由于C语言源代码集相对较小且非常有效,因此C语言源代码可以比高级语言进行更多优化。它几乎可以使用汇编语言进行编程,而无需使用汇编语言进行编程。您甚至可以一起使用Assembly和C!

3)C在固件编程(硬件)中具有其应用。这是由于它具有使用/与装配一起使用以及与装配,控制器和其他设备直接通信的能力。

4)C是许多其他当前已知语言的基础。查看C的历史,您会发现它已经存在了一段时间(无论如何,编程语言还是如此)。以Python为例,例如一种完全面向对象的高级编程语言。它是用C语言编写的(也许也是C ++)。它告诉您是否曾经想知道其他语言的内幕。理解C及其工作原理至关重要。

应用程序语言用于高级编程,例如,编写文字处理器或游戏。应用程序语言的示例是Java,C#。原因是因为它们包含垃圾回收,自动键入,运行时验证等,而重点是生产力。

系统语言用于低级编程。例如,微控制器,驱动程序和OS内核。示例包括汇编C。它们只需要很少的运行时间或不需要运行时间即可直接在硬件上运行代码,并且重点是程序员可以直接控制硬件。

总体而言,它作为一种应用程序语言正在下降,但作为一种系统语言仍然保持着强大的地位。


1

哦,是的,它被使用了。我从事网络数据包处理领域。我去过两家处理网络数据包的公司。因此,我们在以太网或IP级别上运行,而不是在TCP之上的级别上运行。

有趣的是,在两家公司中,C都被选为C ++。在其中一家公司中,两种产品之一是在Linux内核之上构建的,而另一种产品是在Linux用户空间中构建的。内核产品显然使用C,因为Linux内核是用C编程的,但是他们也选择将C用于用户空间产品。两种产品都是从2000年左右开始开发的(内核产品在2000年之前发布,而用户空间产品在2000年之后发布)。

在我后来去的公司中,产品基于C而不是C ++构建。它实际上是1990年代中期以来的一个项目的延续,尽管由于最近对性能的改进要求,所以决定基本上所有内容都将被重写。由于这种重写,我们可以选择C ++,但没有这样做。

在网络数据包处理领域,性能至关重要。因此,我想实现自己的散列表,其性能要比现有散列表高。我不是哈希表作者,而是谁选择要使用的哈希函数。也许我想要性能并选择MurMurHash3。也许我想要安全性并选择SipHash。内存分配器显然是自定义的。实际上,我们使用的所有重要数据结构都是自定义实现的,以实现最高的性能。

尽管没有什么可以阻止C ++的使用,但这通常是一个坏主意。每个数据包抛出一个异常将使数据包处理速率降至无法接受的水平!因此,我们不能使用C ++的异常。太慢了。我们已经通过将数据结构实现为结构,然后实现对这些结构操作的功能,来使用某种面向对象的C代码。C ++允许具有虚函数,但是如果在任何地方使用虚函数,那么虚函数调用将再次降低性能。因此,最好是显式的,并在需要虚拟函数调用时具有函数指针。

C ++将在背后做很多事情:内存分配等。另一方面,在C中通常不会发生。您可以编写一个分配内存的函数,但是通常从该函数的接口可以看出正在发生分配。

作为使用C进行编程时可以进行的微优化的示例,请查看Linux内核中的container_of宏。当然,您可以在C ++代码中使用container_of,但是那是谁呢?我的意思是,这在大多数C程序中都是完全可以接受的,但是典型的C ++程序员会立即提出其他建议,例如将链接节点分配为单独块的链接列表。我们不希望这样,因为每个分配的内存块都会降低性能。

也许对C ++唯一有益的是C ++允许模板元编程,这意味着您有时可以在仍然具有函数参数的同时避免虚拟函数调用,并允许编译器内联函数。但是模板元编程很复杂,我们已经设法满足了C语言中的所有要求,因此C ++中此功能的好处并不是那么关键。

在其中一家公司中,我们实际上使用了一种自定义的编译语言,在其中实现了部分功能。猜猜编译器的目标语言是什么?部件?不,我们必须同时支持32位和64位体系结构。C ++?你当然开玩笑。很显然,这是下用GCC的计算转移。因此,将自定义语言编译为C(或者实际上是C的gcc变体,它支持计算的goto),然后C编译器生成了程序集。


0

我仍然每天都使用C,主要原因之一是与其他语言的互操作以及SDK旨在供各种编译器以各种语言构建的插件使用。

我不能编写一个使用带有构造函数,析构函数和vtable的类,函数重载,引发异常等的C ++ API,这些类可以在Lua,C#,Python,C等中使用。更不用说使用不同编译器编写的C ++插件了和我们自己的设置。

我无法编写可以从Python调用的C#SDK,也不能编写可以从C#调用的Python SDK。

C是这里唯一允许我创建可以从这些语言中的任何一种调用的API的语言。那就是说我经常使用C ++来实现这些C接口(尽管有时我只是在C中实现它们)。

除此之外,我有时会发现C是最简单的语言,可用于底层数据结构和内存分配器。如果要编写旨在分配对齐的位和字节的内存分配器,则在C ++中获得的所有其他类型安全性都无济于事。相对于C ++的丰富类型系统和异常处理,滚动自己的数据结构并不容易-只是看一下写一个数据结构需要花费多少精力,就像std::vector想要使其成为异常安全的并避免调用一样您没有插入到容器中的元素上的ctor和dtors(我是作为实现了整个C ++标准库的人说的)。如果仅很难生长的阵列很难很好地实现,那么可以想象实现生产质量的BVH所需的工作。

当我想使用现有的数据结构或通过使用现有的数据结构实现更高级别的数据结构时,我更喜欢C ++ ,但是如果我要在没有用的引擎核心处实现低级数据结构,使用现有的数据结构,C绝对可以通过它的超级简单类型系统轻松地完成工作,该系统使您可以memcpy在这里和在这里的memmove事物,malloc一个连续的块以及realloc在那里,而不必担心构造函数,析构函数和异常的抛出。

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.