Warum dominiert C ++ in Programmierwettbewerben und Wettbewerben? [geschlossen]

23

Ich verstehe, dass C ++ eine sehr schnelle Sprache ist, aber ist C nicht genauso schnell oder in einigen Fällen schneller?

Dann könnten Sie sagen, dass C ++ OOP hat, aber die Menge an OOP, die Sie für die meisten Programmier-Rätsel benötigen, ist nicht so groß, und meiner Meinung nach wäre C in der Lage, damit umzugehen.

Hier ist der Grund, warum ich dies frage : Ich interessiere mich sehr für das Programmieren von Wettbewerben und Wettbewerben, und ich bin es gewohnt, auf diesen in C zu codieren. Ich habe jedoch festgestellt, dass die überwiegende Mehrheit der Nutzer C ++ verwendet (z. B. 17 von 25 Finalisten bei Google Code Jam 2011 haben es verwendet, während niemand C verwendet hat). Ich frage mich daher, ob ich mit C im Nachteil bin.

Was macht C ++ neben der Objektorientierung zu einer geeigneteren Sprache für Programmierwettbewerbe? Was sind die Merkmale der Sprache, die ich lernen und verwenden sollte, um bei den Wettbewerben bessere Leistungen zu erbringen?

Als Hintergrund betrachte ich mich als ziemlich kompetent in C, aber ich fange gerade erst an, C ++ zu lernen.

Daniel Scocco
quelle

Antworten:

56

Zunächst wird es immer einige Probleme geben, die in einer Sprache besser gelöst werden als in einer anderen. Es wird immer Sprachen geben, die bestimmte Probleme "besser" lösen als jede andere Sprache, für manche Definition von "besser". Eine sehr große Anzahl von Problemen hat jedoch sehr ähnliche Anforderungen (einige E / A, einige Berechnungen) und ähnliche Anforderungen (angemessene Zuverlässigkeit, angemessene Leistung).

Wie Sie bereits wissen, gibt es in C ++ für die meisten Probleme keine nennenswerten Nachteile und eine Reihe von signifikanten Verbesserungen. Fett gedruckt? Manche Leute scheinen das zu glauben, aber das ist wirklich der Fall. Beginnen wir damit, einige sehr häufige C ++ - Missverständnisse auszuräumen:

  • C ++ ist langsamer als C. Falsch! Viele C-Programme sind ebenfalls gültige C ++ - Programme - und ein solches C-Programm sollte beim Kompilieren mit dem C-Compiler oder dem C ++ - Compiler mit identischer Geschwindigkeit ausgeführt werden.

  • C ++ - spezifische Funktionen erfordern Overhead. Falsch! Der sogenannte Overhead, der durch bestimmte C ++ - spezifische Funktionen (wie virtuelle Funktionsaufrufe oder Ausnahmen) eingeführt wird, ist vergleichbar mit dem Overhead, den Sie selbst einführen würden, wenn Sie eine ähnliche Funktion in C implementieren würden.

  • C ++ ist objektorientiert. Falsch! Die C ++ - Sprache enthält einige Spracherweiterungen, die das objektorientierte Programmieren und das generische Programmieren erleichtern. C ++ erzwingt nirgendwo objektorientiertes Design - es erlaubt es nur. C ermöglicht auch objektorientiertes Programmieren, C ++ macht es nur einfacher und weniger fehleranfällig.

Wenn Sie mir glauben, haben wir festgestellt, dass "C ++ nicht wesentlich schlechter ist als C". Werfen wir einen Blick darauf, was C ++ zu einem besseren C macht:

  • Stärkere Typisierung Das Typensystem in C ++ ist stärker als in C. Dies vermeidet viele häufige Programmierfehler - zusammen mit der nächsten sehr wichtigen Funktion ist das stärkere Typensystem sogar kein Problem.

  • Parametrisierte Typen Das Schlüsselwort template ermöglicht es dem Programmierer, generische (typunabhängige) Implementierungen von Algorithmen zu schreiben. Wo in C könnte man eine generische Listenimplementierung mit einem Element schreiben wie:

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

Mit C ++ kann man etwas schreiben wie:

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

Die C ++ - Implementierung verhindert nicht nur häufige Programmiererfehler (wie das Einfügen eines Elements des falschen Typs in die Liste), sondern ermöglicht auch eine bessere Optimierung durch den Compiler! Beispielsweise ist eine generische Sortierimplementierung sowohl in C als auch in C ++ - verfügbar.

Die C-Routine ist definiert als:

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

wohingegen die C ++ - Routine definiert ist als

template void sort(RandomAccessIterator first, RandomAccessIterator last);

Der Unterschied besteht darin, dass zum Beispiel das Sortieren eines Arrays von Ganzzahlen im C-Fall einen Funktionsaufruf für jeden einzelnen Vergleich erfordern würde, wohingegen die C ++ - Implementierung es dem Compiler ermöglichen würde, die Ganzzahlvergleichsaufrufe wie bei der tatsächlichen Sortierroutine inline zu schreiben Wird vom Compiler zur Kompilierungszeit automatisch instanziiert, wobei die richtigen Typen in die Vorlagenargumente eingefügt werden.

  • Eine größere Standardbibliothek C ++ ermöglicht die vollständige Nutzung der C-Standardbibliothek. Dies ist natürlich sehr wichtig, da die C-Standardbibliothek eine unschätzbare Ressource beim Schreiben von Programmen der realen Welt ist. C ++ enthält jedoch die Standardvorlagenbibliothek. Die AWL enthält eine Reihe nützlicher Vorlagen, wie die oben beschriebene Sortierroutine. Es enthält nützliche allgemeine Datenstrukturen wie Listen, Karten, Mengen usw. Wie die Sortierroutine sind auch die anderen AWL-Routinen und Datenstrukturen auf die spezifischen Bedürfnisse des Programmierers "zugeschnitten". Der Programmierer muss lediglich die folgenden Angaben eingeben Typen.

Natürlich ist der STL kein Wundermittel - aber er leistet sehr oft eine große Hilfe bei der Lösung allgemeiner Probleme. Wie oft haben Sie eine Liste in C implementiert? Wie oft wäre ein RB-Baum eine bessere Lösung gewesen, wenn Sie nur die Zeit gehabt hätten, dies zu tun? Mit der STL müssen Sie keine Kompromisse eingehen - verwenden Sie den Baum, wenn er besser passt, so einfach wie die Liste.

Ok, also habe ich nur die guten Teile besprochen. Gibt es irgendwelche Nachteile? Natürlich gibt es. Ihre Zahl nimmt jedoch von Tag zu Tag ab. Lassen Sie mich erklären:

  • Es gibt keine guten C ++ - Compiler. Es ist schon lange so. Aber Sie müssen bedenken, dass die Sprache 1998 standardisiert wurde - es ist eine komplexe Sprache, komplexer als C. Es hat lange gedauert, bis die Compiler den Standard erreicht haben. Zum jetzigen Zeitpunkt gibt es jedoch gute Compiler für die am weitesten verbreiteten Plattformen. GCC in Version 3.X ist im Allgemeinen sehr gut und läuft unter GNU / Linux und den meisten UNIX-Plattformen. Intel hat einen guten Compiler für Win32 - es ist auch ziemlich gut, aber leider stützt es sich immer noch auf die MS STL, die unterdurchschnittlich ist.

  • Die Leute wissen nicht, wie gut C ++ ist. Dies ist keine oft gehörte Beschwerde, aber ich sehe viel davon. C ++ ist eine große und komplexe Sprache - aber es war auch eine Sprache, die besonders in den Tagen "OOP löst Hunger, heilt AIDS und Krebs" vielfach gehypt wurde. Das Ergebnis scheint zu sein, dass eine Menge wirklich schlechter C ++ - Code, im Grunde schlechtes C mit ein paar Klassendeklarationen hier und da, da draußen ist und als Lernmaterial verwendet wird. Dies bedeutet, dass viele Leute, die glauben, C ++ zu kennen, wirklich beschissenen Code schreiben. Das ist schade, und es ist ein Problem, aber ich finde es unfair, C ++ dafür die Schuld zu geben.

Die einzigen zwei Hauptprobleme bei C ++ sind die Ergebnisse, dass C ++ eine junge Sprache ist. Mit der Zeit werden sie verschwinden. Und für die meisten Probleme da draußen sind die Probleme heutzutage kein Problem mehr, wenn Sie gute Programmierer haben (oder gutes C ++ selbst lernen können).

niko
quelle
8
+1. Sehr vollständige Antwort. Ich bin nur anderer Meinung, dass in Zukunft die Hauptnachteile von C ++ verschwinden werden. Da C ++ abwärtskompatibel sein muss, werden fast keine Sprachfunktionen aus C ++ entfernt, sondern nur neue hinzugefügt (C ++ 11 ist hierfür ein perfektes Beispiel). Das wird die Sprache noch komplexer machen als heute, was meiner Meinung nach der größte Nachteil von C ++ ist.
Doc Brown
@DocBrown: Das hängt davon ab, wie Sie C ++ verwenden. Wenn Sie mit viel älterem Code arbeiten, müssen Sie verstehen, wie dies funktioniert, und daher wahrscheinlich umfassende Kenntnisse in C ++ benötigen. Wenn Sie nur neuen Code schreiben (z. B. in einem Wettbewerb), können Sie sich auf das beschränken, was Sie verwenden möchten, und dabei viel Cruft vermeiden (z. B. auto_ptr<>).
David Thornley
Gute Antwort, aber ich denke, "Viele C-Programme sind auch gültige C ++ - Programme" sind nicht stark genug, da die Unterschiede die Codegenerierung nicht verändern. Nahezu jedes C-Programm konnte mit relativ geringem Aufwand als identisch ablaufendes gültiges C ++ - Programm umgeschrieben werden.
Gort the Robot
3

Bei solchen Wettbewerben geht es weniger um die Geschwindigkeit des Programms als vielmehr um die Geschwindigkeit des Programmierers. C ++ verfügt über standardmäßige Bibliotheksfunktionen, Typensicherheit und Hilfe für die Speicherverwaltung, die das Entwickeln und Debuggen beschleunigen, selbst wenn die ausführbare Datei etwas langsamer wird.

Karl Bielefeldt
quelle
2

Als ehemaliger Finalist von Code Jam geht es hauptsächlich um die Bibliotheken und nicht um die Sprachfunktionen. Wettbewerbslösungen verwenden selten OOP-Designprinzipien, aber Sie werden wahrscheinlich einen Rundgang durch die meisten Standard-Bibliothekscontainer und -Algorithmen sehen - Zeichenfolge, Vektor, Liste, Stapel, Warteschlange, Deque, Priority_queue, Satz, Karte, Komplex, Paar, bitset, lower_bound, reverse, sort, find, count, nth_element, min, max, min_element, max_element, unique, next_permutation, ... erfahrene kandidaten kennen sie alle und gewinnen viel zeit, indem sie und nicht implementieren müssen Debuggen Sie sie in C.

Mit Code Jam können Wettbewerber ihren eigenen Code einbringen und Bibliotheken von Drittanbietern verwenden. Theoretisch könnte dies ein Wettbewerber in C vorimplementieren. Dies ist jedoch nicht bei allen Wettbewerben möglich, und Vorlagen und das Überladen von Operatoren machen dies viel lesbarer als in C.

Bruce Merry
quelle