Почему C ++ преобладает в соревнованиях и конкурсах по программированию? [закрыто]

23

Я понимаю, что C ++ - очень быстрый язык, но разве C не такой быстрый или в некоторых случаях более быстрый?

Тогда вы могли бы сказать, что в С ++ есть ООП, но количество ООП, которое вам нужно для большинства задач программирования, не так уж велико, и, по моему мнению, C сможет справиться с этим.

Вот почему я спрашиваю об этом : меня очень интересуют конкурсы и конкурсы по программированию, и я привык программировать на C на них. Тем не менее, я заметил, что подавляющее большинство людей используют C ++ (например, 17 из 25 финалистов в Google Code Jam 2011 использовали его, а никто не использовал C), поэтому мне интересно, если я нахожусь в невыгодном положении по сравнению с C.

Что делает C ++ более подходящим языком для соревнований по программированию, кроме Object Orientation? Какие особенности языка я должен выучить и использовать, чтобы лучше выступать на соревнованиях?

Для справки, я считаю себя довольно опытным в C, но я только начинаю изучать C ++.

Даниэль Скокко
источник

Ответы:

56

Начнем с того, что всегда будут проблемы, которые лучше решить на одном языке, чем на другом. Всегда будут языки, которые решают определенные проблемы «лучше», чем любой другой язык, для некоторого определения «лучше». Однако очень и очень большое количество проблем имеет очень похожие потребности (некоторые операции ввода-вывода, некоторые вычисления) и сталкиваются с аналогичными требованиями (разумная надежность, разумная производительность).

Как вы уже знаете, 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. Компиляторам потребовалось много времени, чтобы догнать стандарт. Но на момент написания этой статьи есть хорошие компиляторы, доступные для наиболее широко используемых платформ; GCC в версиях 3.X, как правило, очень хороши, и он работает на GNU / Linux и большинстве платформ UNIX. У Intel есть хороший компилятор для Win32 - он также довольно хорош, но, к сожалению, он все еще опирается на MS STL, который находится на уровне ниже нормы.

  • Люди не знают хорошего C ++. Это не часто встречающаяся жалоба, но я часто вижу ее. C ++ - это большой и сложный язык, но он также был широко распространенным языком, особенно в те времена, когда ООП решает проблемы голода, лечения СПИДа и рака. В результате получается, что много действительно плохого кода на C ++, в основном плохого C с несколькими объявлениями классов здесь и там, существует и используется в качестве учебного материала. Это означает, что многие люди, которые считают, что знают C ++, на самом деле пишут действительно дрянной код. Это очень плохо, и это проблема, но я думаю, что несправедливо обвинять это в C ++.

Итак, единственными двумя серьезными проблемами с C ++ являются результаты того, что C ++ является молодым языком. Со временем они исчезнут. И для большинства проблем, если вы можете найти хороших программистов (или выучить хороший C ++ самостоятельно), проблемы на самом деле не являются проблемой сегодня.

Niko
источник
8
+1. Очень полный ответ. Единственное, что я придерживаюсь другого мнения, - это то, что в будущем основные недостатки C ++ исчезнут. Поскольку C ++ должен быть обратно совместимым, из C ++ практически не будут удалены языковые функции, добавлены только новые (C ++ 11 - прекрасный пример для этого). Это сделает язык еще более сложным, чем сегодня, что, на мой взгляд, является самым большим недостатком C ++.
Док Браун
@DocBrown: это зависит от того, как вы используете C ++. Если вы работаете с большим количеством старого кода, вам необходимо понять, как это работает, и, следовательно, возможно, вам нужны широкие знания C ++. Если вы просто пишете новый код (например, на соревнованиях), вы можете ограничиться только тем, что вы собираетесь использовать, избегая большого количества беспорядка (как, скажем, auto_ptr<>).
Дэвид Торнли
Хороший ответ, но я думаю, что «многие программы на C также являются действительными программами на C ++» недостаточно сильны, поскольку различия не меняют генерацию кода. Почти каждая программа на C может быть переписана как действительная программа C ++ идентичного исполнения с относительно небольшими усилиями.
Gort the Robot
3

Подобные состязания связаны не столько со скоростью программы, сколько со скоростью программиста. C ++ имеет стандартные функции библиотеки, безопасность типов и справку для управления памятью, что ускоряет разработку и отладку, даже если исполняемый файл заканчивается немного медленнее.

Карл Билефельдт
источник
2

Выступая в качестве финалиста Code Jam, речь идет в основном о библиотеках, а не о языковых возможностях. Конкурентные решения редко используют какие-либо принципы проектирования ООП, но вы, скорее всего, увидите обзор большинства стандартных контейнеров и алгоритмов библиотеки - строки, вектора, списка, стека, очереди, очереди, приоритета, очереди, набора, карты, комплекса, пары, bitset, lower_bound, reverse, sort, find, count, nth_element, min, max, min_element, max_element, unique, next_permutation, ... квалифицированные участники будут знакомы со всеми из них и получат много времени, не выполняя и отлаживать их в C.

Code Jam позволяет участникам вносить свой собственный код и использовать сторонние библиотеки, поэтому теоретически у конкурента все это может быть предварительно реализовано на C. Однако не все конкурсы позволяют это, и шаблоны и перегрузка операторов делают это намного более читабельным. чем в с.

Брюс Мерри
источник