为什么C ++在编程竞赛和竞赛中占主导地位?[关闭]


23

我知道C ++是一种非常快速的语言,但是C会不会变得如此快,或者在某些情况下会更快?

然后您可能会说C ++具有OOP,但是大多数编程难题所需要的OOP数量并不多,我认为C可以处理。

这就是我问这个问题的原因:我对编程竞赛和竞赛非常感兴趣,并且我习惯于用C进行编码。但是,我注意到绝大多数人都使用C ++(例如,在Google Code Jam 2011的25个决赛入围者中有17个使用了C ++,而没有人使用C),所以我想知道我在使用C方面是否处于不利地位。

除了对象定向之外,是什么使C ++更适合编程竞赛的语言?为了在比赛中表现更好,我应该学习和使用哪种语言的功能?

对于背景知识,我认为自己非常精通C,但是我才刚刚开始学习C ++。

Answers:


56

首先,总会有一些问题用一种语言比另一种语言能更好地解决。对于“更好”的某种定义,总会有比其他任何语言都能“更好”地解决特定问题的语言。但是,非常多的问题具有非常相似的需求(一些I / O,一些计算)并且面临着相似的要求(合理的可靠性,合理的性能)。

正如您已经知道的C一样,对于目前存在的绝大多数问题,我指出C ++没有提供任何重大的缺点和许多重大的改进。胆大?有些人似乎是这样认为的,但事实确实如此。让我们首先清除一些非常常见的C ++误解:

  • C ++比C慢。 错!许多C程序也是有效的C ++程序-使用C编译器或C ++编译器进行编译时,此类C程序应以相同的速度运行。

  • C ++特定功能需要开销。错误!某些C ++特定功能(例如虚拟函数调用或异常)引入的所谓开销与您在C中实现类似功能时要引入的开销相当。

  • C ++是面向对象的。错误!C ++语言包含一些语言扩展,可促进面向对象的编程和通用编程。C ++不会在任何地方强制进行面向对象的设计-只是允许这样做。C也允许面向对象的编程,C ++仅使其更简单且不易出错。

因此,如果您相信我,我们已经确定“ C ++不会比C差很多”。让我们看一下是什么使C ++成为更好的C:

  • 更强的类型C ++中的类型系统比C中的类型系统强。这可以防止许多常见的编程错误-再加上下一个非常重要的功能,更强的类型系统甚至不会带来任何不便。

  • 参数化类型 template关键字允许程序员编写算法的通用(与类型无关)实现。在C语言中的什么地方,可以编写具有以下元素的通用列表实现:

    struct element_t {
      struct element_t *next, *prev;
      void *element;
     };
    

C ++允许编写如下内容:

template <typename T>
struct element_t {
   element_t<T> *next, *prev;
   T element;
};

C ++实现不仅可以防止常见的程序员错误(例如,将错误类型的元素放入列表中),还可以使编译器更好地进行优化!例如,通用排序实现在C和C ++中都可用-

C例程定义为:

void qsort(void *base, size_t nmemb, size_t size,
           int(*compar)(const void *, const void *));

而C ++例程定义为

template void sort(RandomAccessIterator first, RandomAccessIterator last);

区别在于,例如,对整数数组进行排序,在C情况下,将需要为每个单个比较调用一个函数,而C ++实现将允许编译器内联整数比较调用,因为实际的排序例程是由编译器在编译时自动实例化,并在模板参数中插入正确的类型。

  • 更大的标准库 C ++允许完全使用C标准库。当然,这非常重要,因为C标准库是编写实际程序时的宝贵资源。但是,C ++包含标准模板库。STL包含许多有用的模板,例如上面的排序例程。它包括有用的通用数据结构,例如列表,映射,集合等。像排序例程一样,其他STL例程和数据结构也“针对”程序员的特定需求“量身定制”-程序员要做的就是填写类型。

当然,STL并非灵丹妙药,但在解决一般问题时,它确实可以提供很大的帮助。您多久在C中实现一个列表?如果只有您有时间去做,RB树多久会是一个更好的解决方案?使用STL,您无需做出任何让步-如果更合适,请使用树,就像使用列表一样容易。

好的,所以我只在讨论好的部分。有没有缺点?当然有。但是,他们的人数每天都在减少。让我解释:

  • 没有好的C ++编译器很久以来就一直这样。但是您必须记住,该语言是1998年标准化的-它是一种复杂的语言,比C语言复杂。编译器要花很长时间才能赶上该标准。但是,在撰写本文时,已经有适用于最广泛使用平台的良好编译器。3.X版中的GCC通常非常好,它可以在GNU / Linux和大多数UNIX平台上运行。英特尔为Win32提供了一个很好的编译器-也很不错,但是不幸的是,它仍然依赖于低于标准的MS STL。

  • 人们对C ++并不了解,这不是经常听到的抱怨,但是我经常看到这一点。C ++是一门庞大而复杂的语言-但它也曾经是一门被大肆宣传的语言,尤其是在“ OOP解决饥饿,治愈艾滋病和癌症”的时代。结果似乎是,很多非常差劲的C ++代码,基本上就是差劲的C语言,到处都有一些类声明,并且在那里被用作学习材料。这意味着许多相信自己知道C ++确实会编写糟糕代码的人。太糟糕了,这是一个问题,但是我认为将此归咎于C ++是不公平的。

因此,C ++仅有的两个主要问题是C ++是一种年轻语言的结果。随着时间的流逝,它们将消失。对于那里的大多数问题,如果您可以找到优秀的程序员(或自己学习优秀的C ++),那么今天的问题就不再是真正的问题了。


8
+1。非常完整的答案。我唯一有不同意见的是,将来,C ++的主要缺点将消失。由于C ++必须向后兼容,因此几乎不会从C ++中删除任何语言功能,而仅添加了新功能(C ++ 11是一个完美的示例)。这将使该语言比今天更加复杂,这是恕我直言,这是C ++的最大缺点。
Doc Brown

@DocBrown:这取决于您如何使用C ++。如果您正在使用许多较旧的代码,则需要了解其工作原理,因此可能需要广泛的C ++知识。如果您只是在编写新代码(例如在比赛中),则可以将自己局限于将要使用的内容,从而避免了很多麻烦(例如auto_ptr<>)。
David Thornley

很好的答案,但是我认为“许多C程序也都是有效的C ++程序”还不够强大,因为差异不会改变代码的生成。几乎每一个C程序都可以用相对较少的努力就可以重写为性能相同的有效C ++程序。

3

像这样的竞赛与程序速度无关,而与程序速度无关。C ++具有标准的库功能,类型安全性和内存管理帮助,即使可执行文件的运行速度稍慢,它也可以加快开发和调试速度。


2

作为以前的Code Jam决赛入围者,它主要是关于库而不是语言功能。竞争解决方案很少使用任何OOP设计原则,但是您很可能会看到大多数标准库容器和算法-字符串,向量,列表,堆栈,队列,双端队列,priority_queue,set,map,complex,pair, bitset,lower_bound,reverse,sort,find,count,nth_element,min,max,min_element,max_element,unique,next_permutation等……熟练的参赛者将对它们全部熟悉,并且无需实施和获得大量时间用C调试它们。

Code Jam允许参赛者输入自己的代码并使用第三方库,因此从理论上讲,参赛者可以在C中预先实现所有这些功能。但是,并非所有竞赛都允许这样做,并且模板和运算符重载使此内容更具可读性比C

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.