Est-ce une bonne habitude d'utiliser des expressions C dans du code C ++?


19

À l'école, nous avons commencé à apprendre le C cette année, malgré le fait que je suis loin devant la classe, et j'ai appris Java, C ++ et C pendant que la classe est à la base de C. Quoi qu'il en soit, je me suis documenté, lu des livres, articles, et j'ai demandé à mon professeur pourquoi je devrais apprendre le C, et elle a dit que c'était le fondement du C ++. Lorsque j'ai commencé à programmer, j'ai trouvé C ++ beaucoup plus facile, j'ai appris plus tard C. Mais dans les livres, vous pouvez voir que le code C fonctionne en C ++ mais qu'il ne va pas vice-versa.

Ma question est assez simple ~ Est-ce une bonne habitude d'utiliser des expressions C en C ++? Laisse moi te donner un exemple:

Si ce code

#include <stdio.h>
#include <iostream>

int main() {
int x;
scanf("%d", &x);
cout << "The number you entered is " << x << "And it's double is " << x*x;
return 0;
}

Soyez plus efficace ou meilleur que ce soit:

#include <iostream>

int main() {
int x;
cin >> x;
cout << "The number you entered is " << x << "And it's double is " << x*x;
return 0;
}

J'ai déjà fait une documentation facile à ce sujet dans certains vieux livres poussiéreux, et d'après ce que j'ai pu trouver, utiliser scanf au lieu de cout vide également le flux ou quelque chose comme ça, donc je demande essentiellement s'il est préférable d'utiliser scanf et dans quels contextes.

Cela s'applique également aux E / S de fichiers car j'ai toujours trouvé que les E / S de fichiers étaient plus faciles en C qu'en C ++. Cette question vaut pour presque toutes les expressions générales en C appliquées au C ++. Il est également notable que j'utilise un compilateur moderne et néanmoins cela ne devrait pas avoir d'importance car je demande si c'est une bonne habitude de programmation d'utiliser des expressions C dans du code C ++.

Il y a probablement des inconvénients et des avantages à le faire, mais je ne cherche qu'un type de réponse oui / pourquoi, non / pourquoi.

Aussi, s'il y a des détails, j'ai laissé un commentaire.


12
Soyez très prudent sur le mélange stdioet iostream. Il y a un certain ordre et synchronisation garantis au sein d'une famille qui ne s'appliquent pas nécessairement à l'extérieur.
David Thornley

Merci pour l'astuce, mais ce morceau de code était un pur exemple. Merci quand même.
Bugster

25
Si vous apprenez la programmation; Vous devez apprendre une indentation appropriée!
bitmask

5
scanf () n'est pas un excellent exemple; il est si terriblement sujet aux erreurs que je vous conseille de l'éviter en C ou C ++.
Russell Borogove

1
Il s'agissait peut-être d'un exemple de code uniquement, mais le commentaire de David va vraiment au cœur du problème pourquoi vous ne devriez pas utiliser les idiomes C lors de la programmation en C ++. Ce sont des langues complètement différentes; ne les confondez pas plus que vous ne confondez Java et C, ou C ++ et Visual Basic.
Cody Gray

Réponses:


36

Non, c'est une mauvaise habitude. Lorsque vous faites cela pour gagner votre vie, vous finirez probablement par violer les guides de style auxquels votre équipe adhère (ou du moins, vous vous frayez un chemin lors des révisions de code).

Oui, cela fonctionne, mais s'il existe un équivalent c ++, utilisez-le. (par exemple, essayez de ne pas mélanger printfsavec couts)


+1 - Court et précis. Et cela met en évidence le point principal de ma réponse que les directives d'équipe aident à rassembler les gens et à les unifier afin qu'ils puissent travailler ensemble.
jmort253

Ce commentaire répond à peu près correctement à ma question et apporte un argument solide. Merci.
Bugster

1
@ThePlan merci. tout le monde avait d'excellentes réponses à cette question.
jglouie

1
Remarque: l'utilisation printfcohérente fonctionnera aussi bien que l'utilisation coutcohérente. Les seuls problèmes sont de les mélanger ensemble et de style.
user253751

Pouvez-vous donner un exemple d'une fonctionnalité en C qui n'a pas d'équivalent C ++?
klutt

20

En général, C et C ++ sont considérés comme s'il s'agissait de deux langages complètement séparés. Par conséquent, il peut être considéré comme une mauvaise forme d'utiliser la syntaxe C dans un programme C ++.

Vous avez raison; cependant, ce code C se compilera très bien. Cela dépend vraiment de la flexibilité de votre entreprise en termes de normes suivantes. Si jamais on me posait la question dans une interview, je serais sûr de faire savoir à l'intervieweur que C fonctionne en C ++, mais aussi que C et C ++ sont deux langages distincts et ne devraient probablement pas être mélangés à moins qu'il y ait un très, très bonne raison de le faire.

Une autre chose à considérer est que les normes aident à créer une plate-forme où plus de personnes peuvent facilement travailler avec du code. Bien que vous ayez eu la chance d'avoir un enseignant qui vous a encouragé à apprendre le C, tout le monde n'est pas aussi chanceux. Par conséquent, mélanger C dans un programme C ++ pourrait être source de confusion pour quelqu'un qui n'a jamais appris C.

En résumé, ce n'est pas parce que vous pouvez faire quelque chose que vous devez le faire, et ce n'est pas parce que vous ne devez pas faire quelque chose que vous ne pouvez pas :)


Je vois. Qu'en est-il de la fonctionnalité, y a-t-il des cas particuliers où la syntaxe C est meilleure que la syntaxe C ++?
Bugster

10

C ++ est rétrocompatible avec C par conception, donc généralement le code C sera compilé par le compilateur C ++ très bien ( généralement parce qu'il y a des mots réservés supplémentaires en C ++ qui ne sont pas en C, et pourraient être utilisés dans le code C interrompant la compilation).

Cependant, je le vois comme une mauvaise pratique de mélange de code. Si vous utilisez scanf- utilisez printf, si vous utilisez operator >>- utilisez operator <<. La raison en est que les opérateurs C ++ surchargés peuvent encapsuler des fonctionnalités que vous ne connaissez pas, et leur inadéquation fera que votre programme fera des choses que vous ne vouliez pas qu'il fasse.

Il n'y a aucune raison particulière de préférer la syntaxe C dans le code C ++, ce sont des langages différents, et lorsque vous utilisez la syntaxe C dans le code C ++ - vous écrivez toujours du code C ++ , mais vous n'utilisez pas beaucoup de ses outils puissants.


5
L'incompatibilité entre C et C ++ est plus que de simples mots-clés. Le système de frappe change, et il existe des fonctionnalités qui existent en C (en particulier C99), qui n'existent pas en C ++. (Par exemple, tableaux de longueur variable).
Arafangion

9

Si nous mettons de côté le style de codage et les problèmes esthétiques, vous rencontrez également divers problèmes techniques lorsque vous utilisez C en code C ++:

  • Qu'est-ce que C? C90, C99 ou C11? Il peut y avoir divers problèmes de compatibilité selon la norme C que vous utilisez. Type booléen, // commentaires, fonctionnalités C99 comme les VLA, initialiseurs désignés, etc.

  • C ++ a un typage plus strict que C. Pour compiler du code C en C ++, vous devez très probablement ajouter différentes transcriptions pour obtenir le type attendu. Cela signifie que vous devrez peut-être réécrire un code C parfaitement fin et de qualité production pour le faire fonctionner en C ++.

  • Les typecasts imposés par une frappe plus stricte ne sont généralement qu'une bonne chose, mais dans certains cas, ils peuvent introduire ou masquer des bogues. Prenons l'exemple infâme du résultat de malloc (). Cela devrait être transtypé en C ++, mais jamais en C. (1)

  • Le mélange des fonctionnalités C et C ++ peut entraîner des bogues et un comportement indéfini. Par exemple, il ne fonctionnera pas pour allouer avec malloc () et libérer avec delete . (2)

  • Problèmes de sécurité des threads. La bibliothèque standard C n'est pas thread-safe. La bibliothèque C ++ standard peut ou non être thread-safe, si c'est le cas, l'ajout d'appels de fonction de bibliothèque C à votre code détruira cela.

    En tant que sidenote pour les programmeurs Windows: le compilateur Visual C ++ a eu un bug de fuite pendant un certain temps, lorsque la fonction CreateThread () de l'API Windows a été utilisée dans le même programme que la bibliothèque C. (3, 4)

  • La convention d'appel peut être un problème sur certains compilateurs, obligeant celui-ci à utiliser extern "C"pour indiquer explicitement quelles fonctions doivent être liées à la "convention d'appel C".

  • Détails ennuyeux. L'opérateur virgule se comporte différemment. La virgule de fin dans les déclarations struct / enum est autorisée en C99 / C11 mais pas en C ++. La portée de divers types de variables et de fonctions est traitée différemment. Etc.

Il y a probablement encore plus de cas.


Les références:

  1. http://c-faq.com/malloc/cast.html
  2. http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.3
  3. http://www.flounder.com/badprogram.htm#CreateThread
  4. http://msdn.microsoft.com/en-us/library/windows/desktop/ms682453%28v=vs.85%29.aspx

7

La raison pour laquelle C ++ peut compiler C est uniquement pour la "compatibilité descendante" (évitez de réécrire le code de travail existant).

Mais C ++ a une philosophie différente par rapport à c. Les mélanger ne fait pas un bon service à tous les deux.

La façon dont C et C ++ gèrent les E / S peut s'appuyer sur une manière différente de gérer l'état interne des E / S. Donc, utilisez au moins les entrées et les sorties de manière cohérente.

Et dans les programmes C ++, respectez le style C ++ (sauf si cela est spécifiquement requis pour le faire ailleurs)


5

Je dirais que l'apprentissage du C en premier est, à mon humble avis, une bonne idée. De cette façon, les gens commencent à comprendre le matériel pour lequel ils écrivent le logiciel.

Mélanger ces deux langues n'est cependant pas une bonne idée. Parce que vous obtenez la complexité insensée de C ++ couplée au twiddling de bits brut commun à C.

Comme vous pouvez le voir, même dans un exemple aussi simple que le vôtre, il existe des problèmes de synchronisation avec différents types de flux et de mise en mémoire tampon interne. Mais aussi, l'approche C & C ++ n'est en aucun cas plus flexible. Passez en classe x, et il n'y a aucun opérateur pour utiliser le streaming et tout ça.

C'est compliqué...

Je pense vraiment qu'un bon programmeur C ++ devrait savoir comment les bits sont retournés derrière chaque construction et quels sont les comportements cachés.

Mais l'apprentissage du C ++, au moins plus de 50% de celui-ci, nécessite plus de 5 ans de codage professionnel, et vous ne pouvez tout simplement pas gérer cela dans le programme qui dure 6 mois avec environ 20 heures d'expérience pratique.

Si j'utilisais des constructions C ++ en C, je n'utiliserais pas de flux, ils sont très simples à vue d'oiseau et font croire aux gens que le développement de logiciels est facile, mais cache des complexités supplémentaires sans beaucoup d'avantages dans de nombreuses situations.

Les classes de wrapper RAII, les modèles, les surcharges, l'exactitude des const et les classes abstraites pures pour les interfaces communes (n'utilisez pas la méthode Java f-ng ici S'IL VOUS PLAÎT!) Sont de bons candidats cependant. Parce qu'ils ajoutent la sécurité, la généralité et la facilité d'utilisation qui sont très importantes pour les projets de la vie réelle. Cependant, n'oubliez pas de vous souvenir de choses comme la destruction virtuelle, la nature explosive de la construction de copie par défaut, la surcharge d'exécution, l'exactitude des const, etc.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.