虽然人们似乎想抱怨 C++,但我还没有找到很多证据证明你为什么要选择C over C++.C似乎没有得到几乎同样多的瑕疵,如果C++有所有这些问题,为什么你不能把自己限制在C子集?你有什么想法/经历?
Joel的回答很好,你可能不得不使用C,尽管还有其他一些:
您必须符合行业准则,这些准则在C中更容易证明和测试.
您有工具可以使用C,但不能使用C++(不仅要考虑编译器,还要考虑所有支持工具,覆盖范围,分析等)
您的目标开发人员是C大师
您正在编写驱动程序,内核或其他低级代码
您知道C++编译器不擅长优化您需要编写的代码类型
您的应用程序不仅不适合面向对象,而且更难以以该形式编写
但在某些情况下,您可能希望使用C而不是C++:
你想要汇编程序的性能,而不需要在汇编程序中编写代码(理论上,C++能够实现'完美'的性能,但编译器并不擅长看到优秀的C程序员会看到的优化)
你正在编写的软件是微不足道的,或几乎是如此 - 扼杀微小的C编译器,编写几行代码,编译并完成所有设置 - 无需打开一个带帮助程序的巨大编辑器,无需编写实际内容空的和无用的类,处理命名空间等等.你可以用C++编译器做几乎相同的事情,只使用C子集,但C++编译器速度较慢,即使对于小型程序也是如此.
您需要极高的性能或小的代码大小,并且知道C++编译器实际上会因为库的大小和性能而难以实现
你认为你可以使用C子集并使用C++编译器进行编译,但是你会发现,如果你这样做,你会得到略有不同的结果,具体取决于编译器.
无论如何,如果你这样做,你就是在使用C.你的问题真的是"为什么C程序员不使用C++编译器?" 如果是,那么你要么不理解语言差异,要么你不理解编译器理论.
我喜欢简约和简约.
因为他们已经知道C.
因为他们正在为只有C编译器的平台构建嵌入式应用程序
因为他们正在维护用C编写的遗留软件
您正在编写操作系统,关系数据库引擎或零售3D视频游戏引擎的级别.
对性能或膨胀的担忧并不是放弃C++的好理由.每种语言都有其潜在的缺陷和权衡 - 优秀的程序员可以了解这些,并在必要时制定应对策略,糟糕的程序员会犯规并责怪语言.
解释Python在许多方面被认为是一种"慢"语言,但对于非平凡的任务,熟练的Python程序员可以轻松地生成比没有经验的C开发人员执行更快的代码.
在我的行业,视频游戏中,我们通过避免内部循环中的RTTI,异常或虚函数等内容在C++中编写高性能代码.这些可能非常有用,但具有可避免的性能或膨胀问题.如果我们要更进一步并完全切换到C,我们将获得很少的东西并失去最有用的C++结构.
偏爱C的最大实际原因是支持比C++更广泛.有许多平台,特别是嵌入式平台,甚至没有C++编译器.
供应商也存在兼容性问题.虽然C具有稳定且定义明确的ABI(应用程序二进制接口),但C++却没有.由于诸如vtable和constructurs/destructors之类的东西,C++中的ABI更加复杂,因此每个供应商甚至是供应商工具链的版本都实现了不同的实现.
实际上,这意味着您不能使用由一个编译器生成的库并将其与代码或另一个库中的库链接,这会为分布式项目或二进制库的中间件提供程序创建噩梦.
我选择用C语写作,因为我喜欢用一种小而紧张的语言.我喜欢访问一个可以在合理的时间内阅读的标准(对我来说 - 我是一个非常慢的读者).而且,我用它来编写嵌入式系统的软件,因为很少有理想的C++编译器存在(比如一些 PIC微控制器).
我采取另一种观点:为什么使用C++而不是C?
" C编程语言"(又名:K&R)一书清楚地告诉你如何在300页以内完成语言所能做的一切.这是极简主义的杰作.没有C++书甚至接近.
显而易见的反驳是大多数(如果不是全部)现代语言也可以这样说 - 他们也无法告诉你如何在几百页内完成所有事情.真正.那么为什么要使用C++呢?功能丰富?功率?如果您需要更丰富或更强大的功能,那么请使用C#,Objective C,Java或类似的东西.为什么要担心C++的复杂性呢?如果您需要C++授予的控制程度,那么我认为使用C. C可以做任何事情并且可以做得很好.
Linus对你的问题的回答是"因为C++是一种可怕的语言"
他的证据充其量只是轶事,但他有一点......
更多的是低级语言,你更喜欢它的C++ .. C++是C,增加了库和编译器支持额外的功能(两种语言都有其他语言没有的功能,并以不同的方式实现),但如果你有使用C的时间和经验,您可以从额外增加的低级别相关功能中受益... [编辑](因为您习惯于手动完成更多工作而不是从语言/编译器本身获得的某些功能中受益)
添加链接:
为什么C++用于嵌入式
你为什么还在使用C?PDF
我会谷歌这个..因为网上已经有很多评论
除了已经提到的其他几点:
少惊喜
也就是说,更容易看到一段代码将完全做什么.在C++中,您需要接近大师级别才能确切地知道编译器生成的代码(尝试模板,多重继承,自动生成的构造函数,虚函数的组合,并混合使用一些命名空间魔术和参数依赖查找).
在许多情况下,这种魔力很好,但是例如在实时系统中,它可能会让你的一天变得糟透了.
因为他们正在编写插件而C++没有标准的ABI.
编译时间长可能很烦人.使用C++,您可以拥有非常长的编译时间(当然,这意味着Stack Overflow会有更多时间!).
我习惯在我的项目中使用C++.然后我找到了一个使用普通C的工作(一个20年前不断发展的AV软件代码库,文档很差......).
C中我喜欢的3件事是:
没有什么是隐含的:你看到你的程序究竟做了什么或不做什么.这使调试更容易.
缺少命名空间和重载可能是一个优点:如果你想知道某个函数的调用位置,只需要查看源代码目录,它就会告诉你.不需要其他特殊工具.
我重新发现了函数指针的强大功能.基本上它们允许你做你在C++中做的所有多态的东西,但它们更灵活.
我很惊讶没有人提到过图书馆.许多语言可以链接到C libs并调用C函数(包括带有extern"C"的C++).C++几乎是唯一可以使用C++库的东西(定义为'使用C++中不在C中的特性的库[比如重载函数,虚方法,重载运算符......],并且不导出一切都通过C兼容接口通过extern"C"').
如果您希望几乎任何程序员都能用C语言来理解您的代码.
因为他们想要使用C99中没有C++等价物的功能.
但是,正如人们第一眼看到的那样,没有那么多对C++有用的C99功能.可变长度数组?C++有std :: vectors.支持复数/虚数?C++有一个模板化的复杂类型.类型通用数学函数?C++重载了标准的数学函数,导致了相同的结果.
命名初始值设定项?不是在C++中,但有一个解决方法:
struct My_class_params { int i; long j; std::string name; My_class_params& set_i(int ii) { i = ii; return *this; } My_class_params& set_j(long jj) { j = jj; return *this; } templateMy_class_params& set_name(STRING&& n) { name = std::forward (n); return *this; } My_class_params() { // set defaults } }; class My_class { My_class_params params; public: My_class(const My_class_params& p) : params(p) { } ... };
这允许你写下这样的东西:
My_class mc(My_class_params().set_i(5).set_name("Me"));
因为对于许多编程任务,C更简单,也足够好.当我特别编写轻量级实用程序时,我觉得C++希望我自己构建一个优雅的超结构,而不是简单地编写代码.
OTOH,对于更复杂的项目,优雅提供了更好的结构严谨性,而不是自然流出键盘.
c ++的大多数重要功能都以某种方式涉及类或模板.除了编译器将这些转换为目标代码的方式之外,这些都是很棒的功能.大多数编译器使用名称修改,而那些不做任何事情的编译器至少就像混乱一样.
如果您的系统独立存在,就像许多应用程序一样,那么C++是一个不错的选择.
如果您的系统需要与不是用C++编写的软件(最常见的是汇编程序或Fortran库)进行交互,那么您就处于紧张状态.要与这些类型的案例进行交互,您需要为这些符号禁用名称重整.这通常是通过声明这些对象来完成的extern "C"
,但它们不能是模板,重载函数或类.如果那些可能是您的应用程序API,那么您将必须使用辅助函数包装它们,并使这些函数与实际实现保持同步.
实际上,C++语言为可以在纯C中轻松实现的功能提供标准语法.
简而言之,可互操作的C++的开销对于大多数人来说太高了.
这很浅,但作为一个忙碌的学生我选择了C,因为我认为C++需要很长时间才能学习.我大学的许多教授都不会接受Python的作业,我需要快速学习.
关于"只使用你想要使用的C++子集"的一句话:这个想法的问题在于强制执行项目中的每个人都使用相同的子集.我自己的观点是松散耦合项目(例如开源项目)的成本相当高,而且C++完全失败了成为一个更好的C,因为你无论在哪里使用C都不能使用C++.
哦,我的C vs C++,一个开始火焰战争的好方法.:)
我认为C更适合驱动程序和嵌入式代码.
C++具有C所没有的一些强大功能,但是当人们编写具有在幕后发生的非明显副作用的代码时,C++的许多面向对象特性会导致巨大的编码混乱.疯狂的代码可以隐藏在构造函数,析构函数,虚函数中...... C代码的美妙之处就是语言在你的背后没有什么不明显的,因此你可以阅读代码而不必查看每个构造函数和析构函数等等.很多问题是有些人编写错误的做法.
我的完美语言将是C99与最安全的C++功能的最小子集的组合,它将ZERO(或接近零)编译器开销添加到二进制输出.完美的补充是类封装和数据和函数的命名概念.