【问题标题】:What are the differences between C, C# and C++ in terms of real-world applications? [closed]就实际应用而言,C、C# 和 C++ 之间有什么区别? [关闭]
【发布时间】:2010-10-16 02:05:55
【问题描述】:

正如我之前在here 发布的那样,我决定尝试其中一个,但鉴于我作为 Web 开发人员的兴趣,我想知道它们在实际应用程序中的区别。

编辑说明:

虽然我是一名网络开发人员,但请不要让这限制了您的回答。我已经 30 岁了……我的职业生涯已经改变了很多年。

【问题讨论】:

  • 您能否说明您是否有兴趣从 Web 应用程序的角度进行比较?
  • 您想继续做一名 Web 开发人员,还是想做一些不同的事情?例如iPhone 应用程序编程语言主要基于 Objective-C

标签: c# c++ c comparison


【解决方案1】:

请记住,我说的是ASFAC++B。 :) 我将最重要的差异化因素放在首位。

垃圾收集

垃圾回收 (GC) 是区分这些语言的最重要因素。

虽然 C 和 C++ 可以与 GC 一起使用,但它是事后才想到的,不能很好地工作 (the best known is here) - 它必须是“保守的”,这意味着它不能收集所有未使用的内存.

C# 从一开始就被设计为在 GC 平台上工作,标准库也以这种方式设计。它对开发人员的生产力产生了绝对根本性的影响,必须亲身体验才能相信。

C/C++ 用户普遍认为 GC 等同于“糟糕的性能”。但这是过时的民间传说(即使是 C/C++ 上的 Boehm 收集器也比大多数人预期的要好得多)。典型的恐惧是程序停止的“长时间停顿”,以便 GC 可以做一些工作。但实际上这些长时间的停顿发生在非 GC 程序上,因为它们运行在虚拟内存系统之上,该系统偶尔会中断以在物理内存和磁盘之间移动数据。

也普遍认为 GC 可以替换为shared_ptr,但它不能;具有讽刺意味的是,在多线程程序中,shared_ptr 比基于 GC 的系统慢。

有些环境如此节俭以至于 GC 不实用 - 但这些环境越来越少见。手机通常有 GC。 C# 通常在其上运行的 CLR 的 GC 似乎是最先进的。

自从大约 18 个月前采用 C# 以来,我已经经历了几个使用分析器进行纯性能调优的阶段,GC 非常高效,在程序运行期间几乎不可见。

GC 不是万能的,它并不能解决所有的编程问题,它只是真正清理内存分配,如果你分配非常大的内存块,那么你仍然需要小心,它仍然是可能的在足够复杂的程序中发生内存泄漏 - 然而,GC 对生产力的影响使其非常接近于灵丹妙药!

未定义的行为

C++ 建立在未定义行为的概念之上。也就是说,语言规范定义了语言特征的某些狭义用法的结果,并将所有其他用法描述为导致未定义的行为,这意味着原则上该操作可能会产生任何结果(实际上这意味着难以诊断的错误涉及明显的非确定性数据损坏)。

几乎所有关于 C++ 的内容都涉及未定义的行为。即使是非常好的即将推出的功能,如 lambda 表达式,也可以很容易地用作破坏堆栈的便捷方式(通过引用捕获本地,允许 lambda 实例比本地更长寿)。

C# 建立在所有可能的操作都应该具有定义的行为的原则之上。可能发生的最坏情况是抛出异常。这彻底改变了软件构建的体验。

(存在不安全模式,它具有指针,因此具有未定义的行为,但强烈建议不要将其用于一般用途 - 将其视为类似于嵌入式汇编语言。)

复杂性

就复杂性而言,C++ 必须单独列出,尤其是考虑到即将标准化的新版本。 C++ 绝对尽其所能使自己有效,而不是假设 GC,因此它有一个很棒的学习曲线。语言设计者通过说“这些功能仅适用于库作者,而不是普通用户”来为这一点辩解——但要在任何语言中真正有效,您需要将代码构建为可重用的库。所以你逃不掉的。

从积极的方面来说,C++ 非常复杂,就像书呆子的游乐场!我可以向您保证,学习如何将它们组合在一起会很有趣。但我不能认真地推荐它作为主流平台上富有成效的新工作(哦,浪费的岁月......)的基础。

C 使语言保持简单(在“编译器易于编写”的意义上简单),但这使得编码技术更加神秘。

请注意,并非所有新的语言功能都等同于增加复杂性。一些语言特性被描述为“语法糖”,因为它们是编译器为您扩展的简写。这是考虑近年来 C# 的大量改进的好方法。语言标准甚至通过将翻译提供给速记来指定一些功能,例如using 语句扩展为 try/finally

在某一时刻,可以以同样的方式考虑 C++ 模板。但从那以后,它们变得如此强大,以至于它们现在构成了该语言整个独立维度的基础,并拥有自己的enthusiastic user communities and idioms

C 和 C++ 最奇怪的地方在于它们没有标准的可互换形式的预编译库。将其他人的代码集成到您的项目中总是有点繁琐,要做出关于如何链接到它的模糊决定。

此外,标准库非常基础——C++ 有一套完整的数据结构和一种表示字符串的方法 (std::string),但这仍然是最小的。是否有在目录中查找文件列表的标准方法?令人惊讶的是,不!是否有用于解析或生成 XML 的标准库支持?不。访问数据库怎么样?严肃点!写一个网站后端?你疯了吗?等等

所以你必须去更远的地方打猎。对于 XML,请尝试 Xerces。但它是否使用std::string 来表示字符串?当然不是!

所有这些第三方库在命名类和函数时都有自己的奇怪习惯吗?你打赌!

C# 中的情况完全不同;基础从一开始就到位,所以一切都可以很好地互操作(而且因为基础是由 CLR 提供的,所以有跨语言支持)。

这并不完美;泛型应该从一开始就存在,但没有,这确实在一些较旧的库上留下了明显的伤痕;但是从外部解决这个问题通常是微不足道的。此外,还有一些流行的库是从 Java 移植而来的,这并不像最初出现的那么合适。

闭包(带有局部变量捕获的匿名方法)

Java 和 C 实际上是最后剩下的缺少闭包的主流语言,使用它们可以设计和使用库比不使用它们时更加整洁(这就是移植的 Java 库有时对 C# 用户来说显得笨拙的原因之一)。

关于 C++ 的有趣之处在于,它的标准库被设计为好像该语言中提供了闭包(容器类型,<algorithm><functional>)。然后十年过去了,现在他们终于被添加了!它们将产生巨大的影响(尽管如上所述,它们泄露了欠精细的行为)。

C# 和 JavaScript 是使用最广泛的语言,其中“惯用地建立”闭包。 (这些语言之间的主要区别在于 C# 是静态类型的,而 JavaScript 是动态类型的)。​​

平台支持

我把它放在最后只是因为它似乎不像你想象的那样区分这些语言。所有这些语言都可以在多种操作系统和机器架构上运行。 C 是最广泛支持的,然后是 C++,最后是 C#(尽管由于名为 Mono 的开源实现,C# 可以在大多数主要平台上使用)。

我在 Windows 和各种 Unix 风格之间移植 C++ 程序的经历令人不愉快。我从未尝试将 C# 中非常复杂的任何东西移植到 Mono,所以我无法对此发表评论。

【讨论】:

  • 这是一个很好的答案,尤其是关于未定义行为和库问题的部分。这两件事在 C++ 世界中引起了很多麻烦,但有时初学者将它们视为优势并捍卫它们。
  • (0) C# 不是跨平台的,算了。 (1) Mono 现在是使 C#“跨平台”的方式,因为它远远落后于 .Net。 (2) C# 缺少一件重要的事情 RAII(不,使用并不能代替它)。 (3) C# 中有一种巨大的未定义非确定性行为,称为 GC。 (4) 关于图书馆...有足够的工具包来完成您想要的所有任务...但是是的,还有不止一个...这是选择的问题。
  • @Artyom - mono 在 C# 3.0 中是最新的,并且在 4.0 发布之前已经在工作。许多实际项目都在使用它。 Novell 正在投资它。 IDisposable/using preciselyexactly 替换了 RAII - 如果您不了解,那么您可能不了解 RAII 本身。认为 GC 未定义也是如此,您显然也不知道 undefined 是什么意思。
  • 我相信他的意思是“非确定性的”,这正是 GC 的意思。从某种意义上说,CLR 的分代垃圾收集器可以被视为未定义的行为,因为您没有明确的保证,任何超过第 1 代的给定对象都会在应用程序终止之前被实际收集。
  • 确实如此 - 但是任何多线程编程也将是非确定性的。 GC 可能不会收集所有对象的事实是无法检测到的,只要它们没有终结器;现在几乎所有终结器的应用程序都被 SafeHandle 所取代,它保证在终止期间被清理。在 C# 中声明未定义行为的一个更明显的目标是不安全块 - 但它们就像一个很少使用的嵌入式 DSL,类似于 C++ 中的汇编语言块。
【解决方案2】:

C 和 C++ 都为您提供了较低级别的抽象,随着复杂性的增加,提供了对其他语言不一定公开的底层机器功能的广泛访问。与 C 相比,C++ 增加了完全面向对象语言的便利性(减少了开发时间),这可能会增加额外的性能成本。就实际应用而言,我看到这些语言在以下领域得到应用:

C

  • 内核级软件。
  • 硬件设备驱动程序
  • 需要访问旧的稳定代码的应用程序。

C,C++

  • 需要微调内存管理的应用程序或服务器开发(不能留给通用垃圾收集解决方案)。
  • 需要访问与更现代的托管语言无法很好交互的库的开发环境。
  • 虽然托管 C++ 可用于访问 .NET 框架,但它不是无缝过渡。

C# 提供了一种托管内存模型,它再次添​​加了更高级别的抽象。这种抽象级别增加了便利性并缩短了开发时间,但使访问较低级别的 API 变得复杂,并使专门的性能要求成为问题。

当然可以在托管内存环境中实现性能极高的软件,但了解其中的含义至关重要。

C# 的语法肯定比 C/C++ 要求低(而且容易出错),并且对于初学者来说,学习曲线更浅。

C#

  • 快速的客户端应用程序开发。
  • 受益于 .NET 框架的高性能服务器开发(例如 StackOverflow)。
  • 需要使用 .NET 框架的设计语言优势的应用程序。

Johannes Rössel 指出使用 C# Pointers、Unsafe 和 Unchecked 关键字突破了构建 C# 的抽象层这一点是有效的。我要强调的是,这种编程类型是大多数 C# 开发场景的例外,而不是语言的基本部分(就像 C/C++ 一样)。

【讨论】:

  • 你仍然可以很好地控制 C# 中使用 unsafe 和 unchecked 等关键字的低级事物;如果你无法逃离 C 世界,你甚至可以使用指针 :)
  • 我想我的观点是,较低级别的抽象是 C 语言的一部分。指针、Unsafe 和 Unchecked 正在脱离 C# 的高级抽象。
【解决方案3】:

C 是准系统、简单、干净的语言,可让您自己完成所有工作。它不会握住你的手,也不会阻止你朝自己的脚开枪。但它拥有你做你想做的一切所需的一切。

C++ 是添加了类的 C,然后是一大堆其他的东西,然后是更多的东西。它不会牵着你的手,但它会让你牵着自己的手,带有附加的 GC 或 RAII 和智能指针。如果您想要完成某些事情,那么很可能有一种方法可以滥用模板系统来为您提供相对简单的语法。 (对于 C++0x 更是如此)。这种复杂性还使您能够意外地创建十几个自己的实例并将它们全部射中。

C# 是微软在 C++ 和 Java 上改进的尝试。大量的语法特性,但远不及 C++ 的复杂性。它在完全托管的环境中运行,因此为您完成了内存管理。它确实让你“弄脏”并在需要时使用不安全的代码,但这不是默认设置,你必须做一些工作才能开枪。

【讨论】:

  • 你能澄清一下“但没有 C++ 的复杂性”吗?很难知道,根据你写的,这是好是坏。我相信我知道你在说什么,但还不清楚。
  • 在我看来没有好坏之分,C# 更容易学习并且没有 C++ 的阴暗角落,但 C++ 的每一点复杂性背后都有一个原因。
【解决方案4】:

我的意见是 C# 和 ASP.NET 将是三者中最好的,用于偏向 Web 的开发。

我怀疑是否有人再用 C 或 C++ 编写新的 Web 应用程序了。它是在 10 年前完成的,可能还有很多遗留代码仍在使用,但它们并不是特别适合,似乎没有那么多(持续的)工具支持,而且它们可能有少量活动进行 Web 开发的社区(可能 Web 服务器开发除外)。我当时写了很多网站 C++ COM 对象,但是 C# 的生产力要高得多,除非你需要,否则没有令人信服的理由来编写 C 或 C++(在这种情况下)。

如有必要,我仍然会编写 C++,但它通常用于小问题域。例如通过 P/Invoke 从 C# 与旧的 C 样式 dll 进行通信 - 在 C# 中做一些完全笨拙的事情是轻而易举地创建一个 C++ COM 对象作为桥梁。

使用 C# 的好处是,您还可以轻松转移到编写 Windows 和控制台应用程序并留在 C# 中。使用 Mono,您也不仅限于 Windows(尽管您可能受限于您使用的库)。

无论如何,这都是从网络偏见的角度来看的。如果您询问嵌入式设备,我会说 C 或 C++。您可能会说这些都不适合 Web 开发,但 C#/ASP.NET 非常漂亮,运行良好,有大量在线资源、庞大的社区和免费的开发工具。

所以从现实世界的角度来看,按照要求只选择 C#、C++ 和 C 中的一个,作为一般规则,您最好坚持使用 C#。

【讨论】:

    【解决方案5】:

    C - 一种较旧的编程语言,被描述为 Hands-on。作为程序员,您必须告诉程序做所有事情。此外,这种语言几乎可以让你做任何事情。它不支持面向对象的代码。因此没有课。

    C++ - C 本身的一种扩展语言。在 C 代码中 ++ 表示增量 1。因此 C++ 比 C 更好。它允许高度受控的面向对象的代码。又一次非常实用的语言,涉及到很多细节。

    C# - 类似于 C/C++ 代码风格的完整面向对象的代码。这真的更接近于JAVA。 C# 是 C 风格语言的最新版本,非常适合开发 Web 应用程序。

    【讨论】:

    • 它们在语法上有何不同?
    【解决方案6】:

    从您的其他帖子中,我猜您想学习一门新语言以获得新技能。我的建议是语言并不是很重要,重要的是其社区的质量(建议,还有你可以阅读和学习的现有代码)和可用的库/框架。在这方面,我认为“C族”对你来说不是最好的选择:Web库和框架很少,不便携也不是很好,你可以学习的代码编码风格变化很大,可能会让你很困惑(虽然 C 是我最喜欢的语言)。

    我建议只学习 C,并尝试真正理解指针的概念,然后转向更适合网络的其他语言(想到 PythonJavaScript - 甚至是 Java)。此外,在我看来,在 C 系列中,Objective-C 是功能和简单性的最佳组合,但却是一个小众玩家。

    【讨论】:

      【解决方案7】:

      C 是最接近并直接转换为 CPU 机器代码的核心语言。 CPU 遵循移动、添加、逻辑组合、比较、跳转、推送和弹出的指令。 C 使用更简单的语法来做到这一点。如果你学习反汇编,你可以学习编写与汇编一样快速和紧凑的 C 代码。它是我在内存有限的 8 位微控制器上的首选语言。如果你用 C 编写一个大型的 PC 程序,你会因为其有限的组织而遇到麻烦。这就是面向对象编程变得强大的地方。 C++ 和 C# 类共同包含数据和函数的能力加强了组织,这反过来又允许在 C 上进行更复杂的可操作性。在过去,当 CPU 只有一个内核时,C++ 对于快速处理至关重要。我现在开始学习 C#。它的类结构似乎比 C++ 执行更高程度的组织,这最终会导致更快的开发并促进代码共享。 C# 不像 VB 那样被解释。它在开发时进行部分编译,然后在运行时进一步翻译以变得更加平台友好。

      【讨论】:

        【解决方案8】:

        对于原始速度,使用 C。对于功率,使用 C++。为了与 .NET 兼容,请使用 C#。

        随着语言的发展,它们都非常复杂; C 经历了数十年的逐渐积累,C++ 经历了多年的快速增强,C# 经历了 Microsoft 的强大。

        【讨论】:

        • 嗯,在很多情况下 C++ 比 C 更快(std::sort vs qsort 就是一个明显的例子)。正如blogs.msdn.com/ricom/archive/2005/05/10/416151.aspx 所示,C# 的性能通常也一样好。要让 C/C++ 比普通的 C# 代码执行得更好,需要做很多工作。
        • 您给出的 C# 的唯一要点是“.net 兼容性”?现在来吧。
        • @jalf:对不起,但你的评论就像比较苹果、橙子和土豆。 C 和 C++ 的速度大致相同(除了不同的代码/库),而 C# 可能永远不会像前者一样快。
        • @jcinacio,由于抖动,.net 代码可能比 c/C++ 更快,视情况而定
        • 我也喜欢 C++/CLI,如果您在进行 .net 编程,它可以为您提供两全其美的体验,尤其是如果您是像我这样的老 C++ 书呆子。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-03-24
        • 1970-01-01
        • 1970-01-01
        • 2013-11-24
        • 2011-05-13
        • 2016-12-05
        • 2010-09-11
        相关资源
        最近更新 更多