Pourquoi le C ++ est-il prédominant dans les concours et compétitions de programmation? [fermé]

23

Je comprends que C ++ est un langage très rapide, mais le C n'est-il pas aussi rapide, ou plus rapide dans certains cas?

Ensuite, vous pourriez dire que C ++ a OOP, mais la quantité d'OOP dont vous avez besoin pour la plupart des puzzles de programmation n'est pas si grande, et à mon avis, C serait capable de gérer cela.

Voici pourquoi je pose la question : je suis très intéressé par la programmation de concours et de compétitions, et j'ai l'habitude de coder en C sur ceux-ci. Cependant, j'ai remarqué que la grande majorité des gens utilisent C ++ (par exemple, 17 finalistes sur 25 sur Google Code Jam 2011 l'ont utilisé, alors que personne n'a utilisé C), donc je me demande si je suis désavantagé avec C.

Mis à part l'orientation objet, qu'est-ce qui fait du C ++ un langage plus approprié pour les compétitions de programmation? Quelles sont les caractéristiques de la langue que je dois apprendre et utiliser pour mieux performer sur les compétitions?

Pour le fond, je me considère assez compétent en C, mais je commence tout juste à apprendre le C ++.

Daniel Scocco
la source

Réponses:

56

Pour commencer, il y aura toujours des problèmes qui seront mieux résolus dans une langue que dans une autre. Il y aura toujours des langues qui résoudront des problèmes spécifiques "mieux" que n'importe quelle autre langue, pour une certaine définition de "mieux". Cependant, un très très grand nombre de problèmes ont des besoins très similaires (certaines E / S, certains calculs) et font face à des exigences similaires (fiabilité raisonnable, performances raisonnables).

Comme vous le savez déjà C, pour la grande majorité des problèmes, je déclare que C ++ ne fournit aucun inconvénient significatif et un certain nombre d'améliorations significatives. Audacieux? Certaines personnes semblent le penser, mais c'est vraiment le cas. Commençons par dissiper quelques malentendus C ++ très courants:

  • C ++ est plus lent que C. Mauvais! De nombreux programmes C sont également des programmes C ++ valides - et un tel programme C doit s'exécuter à une vitesse identique lorsqu'il est compilé avec le compilateur C ou le compilateur C ++.

  • Les fonctionnalités spécifiques à C ++ nécessitent une surcharge. Faux! La surcharge appelée introduite par certaines fonctionnalités spécifiques au C ++ (telles que les appels de fonction virtuelle ou les exceptions), est comparable à la surcharge que vous introduiriez vous-même si vous implémentiez une fonctionnalité similaire en C.

  • C ++ est orienté objet. Faux! Le langage C ++ contient des extensions de langage qui facilitent la programmation orientée objet et la programmation générique. C ++ ne force la conception orientée objet nulle part - il le permet simplement. C permet également la programmation orientée objet, C ++ ne fait que la rendre plus simple et moins sujette aux erreurs.

Donc, si vous me croyez, nous avons établi que "C ++ n'est pas significativement pire que C". Voyons ce qui fait de C ++ un meilleur C:

  • Typage plus fort Le système de type en C ++ est plus fort qu'en C. Cela évite de nombreuses erreurs de programmation courantes - couplé avec la prochaine fonctionnalité très importante, le système de type plus fort parvient même à ne pas être un inconvénient.

  • Types paramétrés Le mot-clé template permet au programmeur d'écrire des implémentations génériques (de type agnostique) d'algorithmes. Où en C, on pourrait écrire une implémentation de liste générique avec un élément comme:

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

C ++ permet d'écrire quelque chose comme:

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

Non seulement l'implémentation C ++ empêche les erreurs de programmation courantes (comme mettre un élément du mauvais type sur la liste), mais elle permet également une meilleure optimisation par le compilateur! Par exemple, une implémentation de tri générique est disponible à la fois en C et C ++ -

la routine C est définie comme:

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

alors que la routine C ++ est définie comme

template void sort(RandomAccessIterator first, RandomAccessIterator last);

La différence étant que, par exemple, le tri d'un tableau d'entiers, dans le cas C, nécessiterait un appel de fonction pour chaque comparaison, tandis que l'implémentation C ++ permettrait au compilateur d'inline les appels de comparaison d'entiers, comme la routine de tri réelle est automatiquement instancié au moment de la compilation par le compilateur, avec les bons types insérés dans les arguments du modèle.

  • Une plus grande bibliothèque standard C ++ permet l'utilisation complète de la bibliothèque standard C. C'est très important bien sûr, car la bibliothèque standard C est une ressource inestimable lors de l'écriture de programmes du monde réel. Cependant, C ++ inclut la bibliothèque de modèles standard. La STL contient un certain nombre de modèles utiles, comme la routine de tri ci-dessus. Il comprend des structures de données communes utiles telles que des listes, des cartes, des ensembles, etc. Comme la routine de tri, les autres routines STL et structures de données sont "adaptées" aux besoins spécifiques du programmeur - tout ce que le programmeur doit faire est de remplir le les types.

Bien sûr, la STL n'est pas une solution miracle - mais elle fournit très souvent une grande aide lors de la résolution de problèmes généraux. À quelle fréquence avez-vous mis en place une liste en C? Combien de fois un arbre RB aurait été une meilleure solution, si seulement vous aviez eu le temps de le faire? Avec la STL, vous n'avez pas besoin de faire de tels compromis - utilisez l'arborescence si elle convient mieux, c'est aussi simple que d'utiliser la liste.

Ok, donc je n'ai discuté que des bonnes parties. Y a-t-il des inconvénients? Bien sûr qu'il y en a. Cependant, leur nombre diminue de jour en jour. Laissez-moi expliquer:

  • Il n'y a pas de bons compilateurs C ++ C'est comme ça depuis longtemps. Mais vous devez vous rappeler que le langage a été normalisé en 1998 - c'est un langage complexe, plus complexe que C. Il a fallu beaucoup de temps aux compilateurs pour rattraper la norme. Mais à ce jour, il existe de bons compilateurs disponibles pour les plates-formes les plus utilisées; GCC dans les versions 3.X est généralement très bon, et il fonctionne sur GNU / Linux et la plupart des plateformes UNIX. Intel a un bon compilateur pour Win32 - il est également assez bon, mais malheureusement, il repose toujours sur le MS STL qui est inférieur à la normale.

  • Les gens ne connaissent pas le bon C ++ Ce n'est pas une plainte souvent entendue, mais c'est quelque chose que je vois beaucoup. Le C ++ est un langage vaste et complexe - mais il était aussi un langage très médiatisé, en particulier à l'époque «La POO résout la faim, guérit le sida et le cancer». Le résultat semble être que beaucoup de code C ++ vraiment pauvre, essentiellement du mauvais C avec quelques déclarations de classe ici et là, est là et est utilisé comme matériel d'apprentissage. Cela signifie que beaucoup de gens qui croient savoir que C ++ écrivent réellement du code vraiment merdique. C'est dommage, et c'est un problème, mais je pense qu'il est injuste de blâmer cela en C ++.

Ainsi, les deux seuls problèmes majeurs avec C ++ sont les résultats de C ++ étant un langage jeune. Avec le temps, ils disparaîtront. Et pour la plupart des problèmes, si vous pouvez trouver de bons programmeurs (ou apprendre vous-même le bon C ++), les problèmes ne sont pas vraiment un problème aujourd'hui.

niko
la source
8
+1. Réponse très complète. La seule chose que j'ai une opinion différente, c'est qu'à l'avenir, les principaux inconvénients du C ++ disparaîtront. Étant donné que C ++ doit être rétrocompatible, il n'y aura presque pas de fonctionnalités de langage supprimées de C ++, seulement de nouvelles ajoutées (C ++ 11 en est un parfait exemple). Cela rendra le langage encore plus complexe qu'il ne l'est aujourd'hui, ce qui est à mon humble avis le plus gros inconvénient de C ++.
Doc Brown
@DocBrown: Cela dépend de la façon dont vous utilisez C ++. Si vous travaillez avec beaucoup de code plus ancien, vous devez comprendre comment cela fonctionne, et donc probablement avoir une large connaissance de C ++. Si vous écrivez simplement du nouveau code (comme dans un concours), vous pouvez vous limiter à ce que vous allez utiliser, en évitant beaucoup de gaspillage (comme, disons, auto_ptr<>).
David Thornley
Excellente réponse, mais je pense que "de nombreux programmes C sont également des programmes C ++ valides" n'est pas assez fort car les différences ne changent pas la génération de code. Presque tous les programmes C pourraient être réécrits en tant que programme C ++ valide à performances identiques avec relativement peu d'efforts.
Gort the Robot
3

De tels concours ne concernent pas tant la vitesse du programme que la vitesse du programmeur. C ++ possède des fonctionnalités de bibliothèque standard, une sécurité de type et une aide à la gestion de la mémoire qui accélèrent le développement et le débogage, même si l'exécutable finit légèrement plus lentement.

Karl Bielefeldt
la source
2

S'exprimant en tant que finaliste de Code Jam, il s'agit principalement des bibliothèques plutôt que des fonctionnalités du langage. Les solutions de la concurrence utilisent rarement des principes de conception OOP, mais vous verrez probablement une visite de la plupart des conteneurs et algorithmes de bibliothèque standard - chaîne, vecteur, liste, pile, file d'attente, deque, priorité_queue, ensemble, carte, complexe, paire, bitset, lower_bound, reverse, sort, find, count, nth_element, min, max, min_element, max_element, unique, next_permutation, ... les candidats qualifiés les connaîtront tous et gagneront beaucoup de temps en n'ayant pas à implémenter et les déboguer en C.

Code Jam permet aux candidats d'apporter leur propre code et d'utiliser des bibliothèques tierces, donc en théorie, un candidat pourrait avoir tout cela pré-implémenté en C. Cependant, tous les concours ne le permettent pas, et les modèles et la surcharge des opérateurs rendent cela beaucoup plus lisible qu'en C.

Bruce Merry
la source