web-dev-qa-db-fra.com

Quand utiliser C sur C ++ et C ++ sur C?

Je suis initié à l'informatique depuis un peu plus d'un an maintenant, et d'après mon expérience, il semble que le C et le C++ soient tous les deux considérés comme des langages "ultrarapides", tandis que d'autres tels que Python et ces langages de script sont généralement considérés comme un peu plus lents.

Mais j'ai également vu de nombreux cas où un projet logiciel ou même un petit entrelacerait des fichiers où un certain nombre n de ces fichiers seraient écrits en C, et un certain nombre m de ces fichiers seraient écrits en C++.

(J'ai également remarqué que les fichiers C++ ont presque toujours des en-têtes correspondants, alors que les fichiers C ne sont pas tellement). Mais mon principal point de recherche est de me faire une idée générale de l’intuition sur le moment où il convient d’utiliser C sur C++, et quand il vaut mieux utiliser C++ sur C. C ne l'est pas, et (2) les syntaxes sont très similaires, et C++ a été intentionnellement créé pour ressembler à C à bien des égards, je ne sais pas quelles sont leurs différences. Il me semble qu'ils sont (presque) parfaitement interchangeables dans de nombreux domaines.

Il serait donc apprécié que quelqu'un clarifie la situation! Merci

164
Dark Templar

Vous choisissez C lorsque

  • vous avez besoin d'un assembleur portable (ce qui est vraiment le C) pour une raison quelconque,
  • votre plateforme ne fournit pas C++ (un compilateur C est beaucoup plus facile à implémenter),
  • vous devez interagir avec d'autres langages qui ne peuvent interagir qu'avec C (généralement le plus petit dénominateur commun sur n'importe quelle plate-forme) et votre code se compose d'un peu plus que l'interface, ce qui ne vaut pas la peine de mettre une interface C sur du code C++,
  • vous piratez un projet Open Source (dont beaucoup, pour diverses raisons , respectez le C),
  • vous ne connaissez pas C++.

Dans tous les autres cas, vous devez choisir C++.

184
sbi

Il y a quelques raisons de préférer C. La principale est qu'il a tendance à être plus difficile de produire des exécutables vraiment minuscules avec C++. Pour les très petits systèmes, vous écrivez rarement beaucoup de code de toute façon, et l'espace supplémentaire ROM qui serait nécessaire pour C++ plutôt que C peut être important).

Je dois également ajouter, cependant, que pour vraiment les petits systèmes, C a des problèmes exactement pour la même raison, et le langage d'assemblage est presque le seul choix raisonnable. La plage de tailles de système dans laquelle C a vraiment du sens est assez petite et rétrécit constamment (même si je l'admets, assez lentement).

Une autre raison/raison d'utiliser C est de fournir un ensemble de fonctions auxquelles vous pouvez vous lier à partir de pratiquement n'importe quel autre langage. Vous pouvez écrire ces fonctions en C++ en les définissant comme extern "C" fonctions, mais cela restreint ces fonctions à présenter un "visage" essentiellement de vie C au monde - classes, fonctions surchargées, modèles, et les fonctions des membres, etc., n'ont pas besoin de s'appliquer. Cependant, cela ne limite pas nécessairement le développement à C - il est parfaitement raisonnable d'utiliser toutes sortes de fonctionnalités C++ en interne , tant que l'interface externe ressemble à C.

En même temps, je dois dire que les réponses de @ Toll (pour un exemple évident) ont des choses à peu près inversées à bien des égards. Un C++ raisonnablement écrit sera généralement au moins aussi rapide que C, et souvent au moins un peu plus rapide. La lisibilité est généralement bien meilleure, ne serait-ce que parce que vous n'êtes pas enfoui dans une avalanche de tout le code, même pour les algorithmes et les structures de données les plus triviaux, toute la gestion des erreurs, etc.

Les modèles ne "résolvent pas un problème avec le système de type du langage", ils ajoutent simplement un certain nombre de capacités fondamentales presque complètement absentes de C et/ou C++ sans modèles. L'une des intentions initiales était de prévoir des conteneurs de type sûr, mais en réalité, ils vont bien au-delà - essentiellement aucun de ceux que C fournit du tout.

Les outils automatisés sont également un hareng rouge - bien qu'il soit vrai que l'écriture d'un analyseur C soit moins de travail que l'écriture d'un analyseur C++, la réalité est que cela ne fait pratiquement aucune différence au final. Très peu de gens sont prêts ou capables d'écrire un analyseur utilisable pour l'un ou l'autre. En tant que tel, le point de départ raisonnable est Clang de toute façon.

En l'occurrence, C et C++ sont assez fréquemment utilisés ensemble sur les mêmes projets, maintenus par les mêmes personnes. Cela permet quelque chose qui est par ailleurs assez rare: un étude qui compare directement et objectivement la maintenabilité du code écrit dans les deux langues par des personnes qui sont globalement tout aussi compétentes (c'est-à-dire les mêmes personnes). Au moins dans l'étude liée, une conclusion était claire et sans ambiguïté: "Nous avons constaté que l'utilisation de C++ au lieu de C entraîne une amélioration de la qualité du logiciel et une réduction des efforts de maintenance ..."

88
Jerry Coffin

Les différences entre C et C++ ont déjà été énumérées en détail ici . Alors que parfois les gens peuvent avoir des raisons légitimes de choisir l'un ou l'autre (C++ pour OOP ou C quand ils ont l'impression que les fonctionnalités supplémentaires de C++ introduisent des frais généraux indésirables, par exemple), d'après mon expérience, cela vient généralement Qu'est-ce que les gens qui travaillent sur ce fichier connaissent mieux et aiment mieux? Je pense que c'est la raison la plupart du temps, car il est vrai que ces langages s'attaquent tous les deux aux applications critiques.

(Note: Vérifiez la diatribe de Linus Torvads sur pourquoi il préfère le C au C++. Je ne suis pas nécessairement d'accord avec ses points, mais cela vous donne un aperçu de la raison pour laquelle les gens pourraient choisir le C plutôt que le C++. Les personnes qui sont d'accord avec lui pourraient plutôt choisir C pour ces raisons.)

24
Casey Patton

Le principal problème manquant dans les réponses existantes (au moment de cette publication) est le choix.

C'est simple. Si, pour une raison absolument irrationnelle, vous pensez que les exceptions ne valent pas la surcharge, alors vous n'avez pas à les utiliser. Vous pouvez toujours avoir des modèles, RAII et la bibliothèque Standard, et ne jamais écrire un seul "lancer". Il en va de même pour les modèles. Si, pour une raison quelconque, vous pensez qu'ils provoquent un ballonnement exécutable irrévocable (et en fait important, qui ne se trouve que sur le système embarqué), alors surprise - vous pouvez également utiliser void * et sizeof (T) toute la journée. Rien ne vous oblige à utiliser l'une des fonctionnalités C++ sur C.

C'est pourquoi C++ est un langage intrinsèquement supérieur - vous pouvez choisir les fonctionnalités que vous voulez et revenir à la programmation de style C lorsque vous n'aimez pas une fonctionnalité donnée. Par conséquent, étant donné que C++ est tout ce que C est et plus, il est évident que C++ est un langage supérieur. Suggérer autrement, c'est comme essayer de suggérer que 4 est supérieur à 5.

13
DeadMG

Choses sur C++ qui rendent les programmeurs C nerveux

Il y a beaucoup de magie sous le capot; Les constructeurs, destructeurs, méthodes virtuelles, modèles, etc., peuvent rendre le code C++ beaucoup plus facile et plus rapide à écrire que le code C équivalent, mais plus difficile à comprendre et à raisonner (selon votre connaissance du C++ et de ses conventions associées). Quelque chose d'aussi simple que Foo newFoo; peut invoquer un lot de code, selon la façon dont le constructeur de la classe Foo (et les classes dont il dépend) a été défini. C'est aussi pourquoi la convention est d'écrire ++it au lieu de it++ lors de l'itération dans un conteneur, car postfix ++ implique souvent une opération de copie coûteuse.

Selon ce que vous faites, il peut y avoir des frais généraux non triviaux, en particulier pour les tâches simples. Prenez les deux programmes suivants, le premier en C, le second en C++:

/* C version */
#include <stdio.h>
int main(void)
{
  char greeting[] = "Hello, world";
  printf("%s\n", greeting);
  return 0;
}
/* end C version */

/* C++ version */
#include <iostream>
#include <string>
int main(void)
{
  std::string greeting("Hello, world");
  std::cout << greeting << std::endl;
  return 0;
}
/* end C++ version */

Comportement identique, pas beaucoup de différence en termes de source, mais sur la box SLES 10 sur laquelle je travaille avec gcc 4.1.2, le premier génère un exécutable de ~ 9kb, alors que le second prend plus de 12,5kb (pas d'optimisation ), près de 28% plus grand. Le type C++ string est beaucoup plus facile à travailler avec IMO que la bibliothèque de chaînes C, et les flux C++ sont beaucoup plus flexibles et personnalisables que les flux C, mais pour un code vraiment cérébral comme celui-ci, ils peut ne pas valoir les frais généraux.

C++ est un langage énorme par rapport au C, avec une sémantique extrêmement complexe. Il faut beaucoup plus de temps pour maîtriser le C++ que le C, ce qui signifie que beaucoup de gens qui prétendent connaître le C++ ne le savent pas aussi bien qu'ils le pensent.

Choses sur C qui rendent les programmeurs C++ nerveux

C n'est pas un langage de programmation sécurisé par aucun effort d'imagination; aucune vérification des limites sur les tableaux ne conduit à de nombreux comportements exploitables (que ce soit via la fonction gets maintenant morte, ou via scanf avec le %s et %[ spécificateurs de conversion). C++ vous donne au moins des conteneurs qui lèvent des exceptions si vous essayez d'accéder en dehors de leur plage actuellement définie; tout ce que C vous donne est (si vous êtes chanceux) une violation de segmentation.

La gestion de la mémoire en C est très laborieuse et sujette aux erreurs, par rapport aux outils fournis par C++. Si vous créez votre propre conteneur, vous êtes responsable de la mise en correspondance de tous les appels malloc et free, en vous assurant que les allocations sont réussies, en supprimant toutes les allocations partielles en cas d'erreur , etc. En C++, vous ajoutez ou supprimez simplement des éléments du conteneur. S'il y a un problème, une exception sera levée.

De même, la gestion des erreurs en C est une douleur dans le cul par rapport aux outils fournis par C++ (à savoir, les exceptions). Ce qui est vraiment amusant, c'est lorsque vous avez alloué un tas de mémoire, puis frappé un mur dans votre traitement; comme vous devez reculer, vous devez libérer cette mémoire dans le bon ordre. Avec les principes C++ et RAII, c'est (relativement) facile à faire.

Alors, quand dois-je utiliser l'un sur l'autre?

Si ce que vous écrivez est un marécage simple, lisez-le/détrompez-vous/débarrassez-vous de l'application, dont le comportement peut être décrit clairement en termes d'entrées et de sorties, et les performances sont importantes, alors préférez C à C++. Sinon, préférez C++

9
John Bode

Bjarne Stroustrup maintient une liste des applications et des entreprises qui utilisent C++; vous pouvez discuter de la procédure vs OOP programmer tout ce que vous voulez, mais vous ne pouvez pas contester les résultats de l'industrie au cours des 20 dernières années.

Le C++ est couramment utilisé pour les projets complexes à grande échelle, multi-hommes où des personnes distinctes doivent travailler sur des composants modulaires. Vous pouvez bien sûr créer et maintenir du code modularisé en C, mais la nature intrinsèque OOP de C++ conduit à une modularisation, une testabilité et une réutilisation du code supérieures.

La bibliothèque standard C++ (STL), en elle-même avec seulement des vecteurs et des cartes, est une raison suffisante pour utiliser C++.

C est couramment utilisé pour les systèmes embarqués.

Personnellement, j'utiliserais C uniquement s'il existe une bibliothèque qui n'a qu'une API C.

9

Je dirais que la principale raison pour laquelle je choisirais le C plutôt que le C++, c'est seulement quand je devrais recourir à "Ce que cela DOIT ÊTRE 1000% stable".

C++ est ~ 99% C quand on regarde les performances, et c'est beaucoup plus productif. Ainsi, même en C, vous pouvez écrire du code qui sera plus rapide que C++ (vous pouvez également utiliser un sous-ensemble de C++ sans exception, virtuel, streaming, abstractions, etc., mais c'est essentiellement C), le temps d'optimiser chaque putain de chose alors que STL est testé et le fait déjà, cela vous coûterait plus que le gain de performance minime que vous pourriez réaliser, ou sacrifier parce que les algorithmes STL ont été écrits par des groupes d'experts, et vous n'êtes probablement pas un expert en tout.

D'un autre côté, C++ a une tonne d'abstractions. Lorsqu'elles fuient dans des circonstances, cela vous cause des ennuis. Et il y a peu de gens qui connaissent à 100% les accrochages C++, alors que, je suppose, il y en a plus qui connaissent tous les accrochages C, donc écrire une solution où chaque étape est entièrement comprise par tous les membres d'une équipe est beaucoup plus facile en C.

Exemple: savez-vous quand shared_ptr<smthn> va déborder son nombre de références, va-t-il lever une exception? Des choses comme celles-ci ne sont pas cool quand Shuttle doit rentrer dans l'atmosphère, du moins je suppose.

De plus, la gestion des exceptions est très, très difficile par rapport aux codes d'erreur. Il est difficile de voir si la classe est 100% sans danger pour les exceptions et facile à détecter les fuites. Beaucoup de gens de haut niveau ont exprimé cette opinion.

9
Coder

C est un assemblage portable avec une meilleure syntaxe, donnant au programmeur le contrôle total de tout.

C++ d'autre part, fait beaucoup de magie funky (fonctions virtuelles, surcharge, conversion automatique, etc.) qui peut ne pas être souhaitable lorsque vous voulez vous assurer que vous:

  • n'utilisez pas plus de mémoire que vous ne le souhaitez
  • n'accédez pas aux pages mémoire volontairement (la vtable peut être n'importe où)
  • n'invoquez pas trop de code accidentellement

Et voulez quelque chose de vraiment simple à travailler, car vous êtes concentré sur la performance.

Il n'a tout simplement pas de surprises, et c'est très précieux.

Si vous le souhaitez (et je le recommande), lisez les directives de codage JSF sur ce à quoi vous devez penser lorsque vous écrivez du C++ pour le contrôle d'avionique militaire. Vous devez être conscient de nombreux pièges et cela peut vous attraper. Bjarne faisait partie de ce document, alors il sait de quoi il s'agit.

De plus, C compile comme un troll échaudé frappé par la foudre. C++, OTOH, a probablement été parrainé par les mêmes personnes qui ont investi dans les entreprises de SSD. :)

(Personnellement, je préfère le C++, mais je ne l'aime pas non plus ...... ;-P)

6
Macke

(étant donné que vous connaissez également les deux langues)

Allez avec C++ à moins qu'il n'y ait pas de compilateur C++ pour votre plateforme. Vous pouvez écrire du code C++ sans aucune portion du langage que vous n'aimez pas (pas de classes, d'exceptions, d'héritage virtuel, quelles que soient les restrictions personnelles que vous souhaitez appliquer), puis à un moment donné dans le futur, si vous décidez que vous voulez après tout, vous pouvez facilement les utiliser. Rien en C++ ne vous empêche d'écrire du code de style C.

(étant donné les ensembles d'outils et les connaissances des développeurs équivalents) Il n'y a aucune raison de choisir C plutôt que C++ à condition que votre plateforme dispose d'un compilateur C++. Vous pouvez simplement vous limiter au sous-ensemble de la langue que vous souhaitez aujourd'hui, tout en laissant la porte ouverte pour une extension ultérieure.

2
anon

Les deux langues sont excellentes. Je pense qu'un certain nombre d'affiches ont détaillé les forces et les diverses utilisations de chacune. J'ajouterai simplement ceci:

Je vois le langage C parfait dans 4 domaines: 1) Je pense que c'est le meilleur langage à utiliser lors de la première apprentissage de tout type de programmation [combiné à un assemblage et une connaissance du code machine], 2) il est idéal pour écrire des pilotes, 3) intégré logiciel, et 4) logiciel système au niveau le plus bas.

Le C++ est un langage orienté objet, mais il peut également être procédural (très similaire à C). Si vous travaillez sur des projets à grande échelle, des logiciels basés sur une interface graphique, des logiciels de jeux et d'autres types de logiciels à forte intensité graphique, je trouve que C++, Java ou même Objective-C sont votre meilleur choix. Cependant, il existe de nombreux programmes en ligne de commande ou logiciels système dans lesquels C++ peut être aussi bon ou meilleur que C.

1
Jonathan

C est probablement préférable à C++ lorsque le code C est généré (par exemple dans les implémentations de langages de niveau supérieur). Par exemple, il existe plusieurs compilateurs de type LISP qui émettent du code C (par exemple Chicken , Scheme48 ...), mais je n'en connais aucun qui émette du code C++ authentique (mon - MELT l'outil émet du code C++, mais je n'appellerai pas ce code un véritable code C++, il utilise très peu de fonctionnalités C++).

Le code C est également plus facile à prouver semi-automatiquement. Des analyseurs statiques comme Frama-C (où vous annotez votre code C avec des commentaires ACSL pour aider la raison du prouveur à propos de votre code) sont disponibles pour C, mais pas beaucoup pour C++ 11 complet.

0

À mon avis, il manque un point dans cette discussion: il est plus simple en C de fournir une interface binaire stable à partir d'une bibliothèque. Tant pour une utilisation avec d'autres langages que C++.

En C++, différents compilateurs utilisent un changement de nom différent afin que les consommateurs d'une bibliothèque compilée avec un compilateur différent de la bibliothèque puissent avoir des problèmes à l'utiliser. Avec C, l'interface binaire est généralement normalisée pour la plate-forme.

Je sais que les compilateurs de nos jours ont souvent des commutateurs pour produire des choses compatibles avec gcc, mais cela n'aide pas toujours.

J'observe cela sur Solaris assez souvent. La distribution et les différents éditeurs de logiciels utilisent généralement Sun Studio car, en particulier sur les systèmes Sparc, ils fournissent souvent de meilleurs résultats. Les projets man open source sont écrits avec du code spécifique à gcc. Cela peut être assez pénible de les faire travailler ensemble.

0
johannes