Ist es eine gute Angewohnheit, C-Ausdrücke in C ++ - Code zu verwenden?

19

In der Schule haben wir dieses Jahr angefangen, C zu lernen, obwohl ich der Klasse weit voraus bin, und ich habe Java, C ++ und C gelernt, während die Klasse an der Basis von C ist. Jedenfalls habe ich mich selbst dokumentiert, Bücher gelesen, Artikel, und ich habe meine Lehrerin gefragt, warum ich C lernen soll, und sie sagte, es sei die Grundlage von C ++. Als ich mit dem Programmieren anfing, fand ich C ++ viel einfacher, später lernte ich C. Aber in Büchern kann man sehen, dass C-Code in C ++ funktioniert, aber nicht umgekehrt.

Meine Frage ist ziemlich einfach ~ Ist es eine gute Angewohnheit, C-Ausdrücke in C ++ zu verwenden? Lassen Sie mich Ihnen ein Beispiel geben:

Sollte dieser 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;
}

Seien Sie in irgendeiner Weise effizienter oder besser:

#include <iostream>

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

Ich habe dies bereits in einigen staubigen alten Büchern leicht dokumentiert, und nach allem, was ich finden konnte, spült die Verwendung von scanf anstelle von cout auch den Stream oder ähnliches. Daher frage ich mich im Grunde, ob es besser ist, scanf und in zu verwenden welche Zusammenhänge.

Dies gilt auch für Datei-E / A, da ich immer festgestellt habe, dass Datei-E / A in C einfacher ist als in C ++. Diese Frage betrifft so ziemlich jeden allgemeinen Ausdruck in C, der auf C ++ angewendet wird. Es ist auch bemerkenswert, dass ich einen modernen Compiler verwende und dies sollte dennoch keine Rolle spielen, da ich frage, ob es eine gute Programmiergewohnheit ist, C-Ausdrücke in C ++ - Code zu verwenden.

Es gibt wahrscheinlich Vor- und Nachteile, aber ich suche nur nach einer Antwort mit Ja / Warum, Nein / Warum.

Auch wenn es irgendwelche Details gibt, habe ich einen Kommentar ausgelassen.

Bugster
quelle
12
Seien Sie sehr vorsichtig beim Mischen stdiound iostream. Innerhalb einer Familie ist eine bestimmte Reihenfolge und Synchronisierung garantiert, die nicht unbedingt außerhalb der Familie gilt.
David Thornley
Danke für den Tipp, aber dieser Codeabfall war ein reines Beispiel. Danke trotzdem.
Bugster
25
Wenn Sie Programmieren lernen; Sie müssen die richtige Einrückung lernen!
Bitmaske
5
scanf () ist kein gutes Beispiel. Es ist so furchtbar fehleranfällig, dass ich Ihnen raten würde, es in C oder C ++ zu vermeiden.
Russell Borogove
1
Es könnte nur Beispielcode gewesen sein, aber Davids Kommentar bringt die Frage auf den Punkt, warum Sie bei der Programmierung in C ++ keine C-Idiome verwenden sollten . Sie sind völlig andere Sprachen; Verwechseln Sie sie nicht mehr als Java und C oder C ++ und Visual Basic.
Cody Grey

Antworten:

36

Nein, es ist eine schlechte Angewohnheit. Wenn Sie dies für Ihren Lebensunterhalt tun, werden Sie wahrscheinlich gegen Style-Guides verstoßen, die Ihr Team befolgt (oder zumindest bei Code-Überprüfungen verprügelt werden).

Ja, es funktioniert, aber wenn es ein C ++ - Äquivalent gibt, verwenden Sie es. (zB nicht mischen printfsmit couts)

jglouie
quelle
+1 - Kurz und bündig. Dies unterstreicht den Hauptpunkt meiner Antwort, dass Teamrichtlinien dabei helfen, Menschen zusammenzubringen und zu vereinen, damit sie zusammenarbeiten können.
jmort253
Dieser Kommentar beantwortet meine Frage ziemlich genau und liefert ein solides Argument. Vielen Dank.
Bugster
1
@ThePlan danke. Alle hatten großartige Antworten auf diese Frage.
Jglouie
1
Hinweis: printfKonsistentes Verwenden funktioniert genauso gut wie coutkonsistentes Verwenden . Die einzigen Probleme sind das Zusammenmischen und der Stil.
user253751
Können Sie ein Beispiel für ein Feature in C geben, für das es kein C ++ - Äquivalent gibt?
Klutt
20

Im Allgemeinen werden C und C ++ als zwei völlig separate Sprachen betrachtet. Daher kann die Verwendung von C-Syntax in einem C ++ - Programm als fehlerhaft angesehen werden.

Du hast Recht; Dieser C-Code kann jedoch problemlos kompiliert werden. Es kommt wirklich darauf an, wie flexibel Ihr Unternehmen in Bezug auf die Einhaltung von Standards ist. Wenn mir jemals eine Frage in einem Interview gestellt würde, würde ich den Interviewer sicher wissen lassen, dass C in C ++ funktioniert, aber auch, dass C und C ++ zwei getrennte Sprachen sind und wahrscheinlich nicht gemischt werden sollten, es sei denn, es gab eine sehr, sehr guter Grund dafür.

Zu berücksichtigen ist auch, dass Standards dazu beitragen, eine Plattform zu schaffen, auf der mehr Menschen problemlos mit Code arbeiten können. Obwohl Sie das Glück hatten, einen Lehrer zu haben, der Sie ermutigte, C zu lernen, kann es sein, dass nicht jeder so glücklich ist. Daher kann das Mischen von C in einem C ++ - Programm für jemanden verwirrend sein, der C noch nie gelernt hat.

Zusammenfassend bedeutet es nicht, dass Sie etwas tun können, und nur, dass Sie etwas nicht tun sollten, bedeutet nicht, dass Sie es nicht können :)

jmort253
quelle
Aha. Was ist mit der Funktionalität? Gibt es bestimmte Fälle, in denen die C-Syntax besser ist als die C ++ - Syntax?
Bugster
10

C ++ ist abwärtskompatibel mit C, weshalb C-Code normalerweise vom C ++ - Compiler kompiliert wird ( normalerweise, weil es in C ++ zusätzliche reservierte Wörter gibt, die sich nicht in C befinden und in C-Code verwendet werden können, der die Kompilierung unterbricht).

Ich sehe es jedoch als schlechte Praxis, Code zu mischen. Wenn Sie scanf- verwenden printf, wenn Sie operator >>- verwenden operator <<. Der Grund dafür ist, dass die überladenen C ++ - Operatoren möglicherweise Funktionen enthalten, die Ihnen nicht bekannt sind. Wenn Sie nicht übereinstimmen, führt dies dazu, dass Ihr Programm Aufgaben ausführt, die Sie nicht ausführen möchten.

Es gibt keinen besonderen Grund, C-Syntax in C ++ - Code zu bevorzugen. Dies sind verschiedene Sprachen. Wenn Sie C-Syntax in C ++ - Code verwenden, schreiben Sie immer noch C ++ - Code, verwenden aber nicht viele seiner leistungsstarken Tools.

littleadv
quelle
5
Die Inkompatibilität zwischen C und C ++ ist mehr als nur Schlüsselwörter. Das Eingabesystem ändert sich, und es gibt Funktionen in C (insbesondere C99), die in C ++ nicht vorhanden sind. (ZB Arrays variabler Länge).
Arafangion
9

Wenn wir den Codierungsstil und die ästhetischen Probleme beiseite lassen, gibt es auch verschiedene technische Probleme, die bei der Verwendung von C in C ++ auftreten:

  • Was ist C? C90, C99 oder C11? Abhängig vom verwendeten C-Standard können verschiedene Kompatibilitätsprobleme auftreten. Boolescher Typ, // Kommentare, C99-Funktionen wie VLAs, festgelegte Initialisierer usw.

  • C ++ hat eine strengere Typisierung als C. Um C-Code in C ++ zu kompilieren, müssen Sie höchstwahrscheinlich verschiedene Typumwandlungen hinzufügen, um den erwarteten Typ zu erhalten. Dies bedeutet, dass Sie möglicherweise perfekten C-Code in Produktionsqualität neu schreiben müssen, damit er in C ++ funktioniert.

  • Die durch eine strengere Eingabe erzwungenen Typumwandlungen sind im Allgemeinen nur eine gute Sache, aber in einigen Fällen können sie Fehler einführen oder verbergen. Nehmen Sie die berüchtigte Besetzung des Ergebnisses aus malloc () als Beispiel. Dies sollte in C ++ geschrieben werden, jedoch niemals in C. (1)

  • Das Mischen von C- und C ++ - Funktionen kann zu Fehlern und undefiniertem Verhalten führen. Zum Beispiel wird es nicht funktionieren, mit malloc () zuzuweisen und mit delete freizugeben . (2)

  • Thread-Sicherheitsprobleme. Die C-Standardbibliothek ist nicht threadsicher. Die Standard-C ++ - Bibliothek kann thread-sicher sein oder auch nicht. Wenn Sie dann C-Bibliotheksfunktionsaufrufe zu Ihrem Code hinzufügen, wird dies zerstört.

    Als Randnotiz für Windows-Programmierer: Der Visual C ++ - Compiler hatte einige Zeit einen Leak-Bug, als die Windows-API-Funktion CreateThread () im selben Programm wie die C-Bibliothek verwendet wurde. (3, 4)

  • Das Aufrufen von Konventionen kann bei einigen Compilern ein Problem darstellen, da sie gezwungen sind extern "C", explizit anzugeben, welche Funktionen mit der "C-Aufrufkonvention" verknüpft werden sollen.

  • Nervige Details. Kommaoperator verhält sich anders. In C99 / C11 ist das nachstehende Komma in Struct / Enum-Deklarationen zulässig, nicht jedoch in C ++. Der Umfang verschiedener Arten von Variablen und Funktionen wird unterschiedlich behandelt. Usw.

Es gibt wahrscheinlich noch mehr Fälle.


Verweise:

  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

quelle
7

Der Grund, warum C ++ C kompilieren kann, ist nur aus Gründen der "Abwärtskompatibilität" (vermeiden Sie es, vorhandenen Arbeitscode neu zu schreiben).

C ++ hat jedoch eine andere Philosophie als c. Sie zu vermischen ist für beide kein guter Dienst.

Die Art und Weise, wie C und C ++ E / A verwalten, kann sich auf eine andere Art und Weise auf die Verwaltung des internen E / A-Zustands stützen. Verwenden Sie also zumindest die Ein- und Ausgabe konsistent.

Und in C ++ - Programmen muss der C ++ - Stil beachtet werden (sofern nicht anderswo ausdrücklich erforderlich).

Emilio Garavaglia
quelle
5

Ich würde sagen, dass es eine gute Idee ist, zuerst C zu lernen. Auf diese Weise verstehen die Leute die Hardware, für die sie die Software schreiben.

Das Mischen dieser beiden Sprachen ist jedoch keine gute Idee. Weil Sie die verrückte Komplexität von C ++ in Verbindung mit dem in C üblichen rohen Bit-Twiddling erleben.

Wie Sie sehen, gibt es selbst in einem so einfachen Beispiel wie dem Ihren Synchronisierungsprobleme mit verschiedenen Arten von Streams und interner Pufferung. Aber auch der C & C ++ - Ansatz ist keineswegs flexibler. Wechseln Sie zur Klasse x, und es gibt keine Operatoren, die Streaming und ähnliches verwenden könnten.

Es ist kompliziert...

Ich denke wirklich, dass ein guter C ++ - Programmierer wissen sollte, wie die Bits hinter jedem Konstrukt gespiegelt werden und was die verborgenen Verhaltensweisen sind.

Aber das Erlernen von C ++, mindestens mehr als 50% davon, erfordert mehr als 5 Jahre professionelles Codieren, und das kann man im 6-monatigen Lehrplan mit etwa 20 Stunden praktischer Erfahrung einfach nicht schaffen.

Wenn ich C ++ - Konstrukte in C verwenden würde, würde ich keine Streams verwenden, da diese aus der Vogelperspektive einfach sind und die Leute glauben machen, dass die Softwareentwicklung einfach ist, aber zusätzliche Komplexitäten in vielen Situationen ohne großen Nutzen verbergen.

RAII-Wrapper-Klassen, Templates, Überladungen, Konstanten-Korrektheit und reine abstrakte Klassen für gemeinsame Interfaces (verwenden Sie hier jedoch nicht die f-ng Java-Methode, BITTE!) Sind gute Kandidaten. Weil sie Sicherheit, Allgemeingültigkeit und Benutzerfreundlichkeit hinzufügen, die für Projekte im realen Leben sehr wichtig sind. Denken Sie aber auch hier an Dinge wie virtuelle Zerstörung, die Brisanz der Standard-Kopierkonstruktion, Laufzeit-Overhead, Konstanten-Korrektheit usw.

Coder
quelle