it-swarm.com.de

Was sind die Unterschiede zwischen C, C # und C++ in Bezug auf die reale Anwendung

Wie ich vorhin hier gepostet habe, habe ich beschlossen, mich in einem dieser Bereiche zu versuchen, möchte aber angesichts meiner Interessen als Webentwickler den Unterschied zwischen ihnen in ihren realen Anwendungen kennen.

Anmerkung bearbeiten:

Ich bin zwar ein Webentwickler, aber bitte lassen Sie Ihre Antwort nicht einschränken. Ich bin 30 ... Ich habe noch Jahre Karriere vor mir.

36
jerebear

Sowohl C als auch C++ bieten Ihnen eine geringere Abstraktionsebene, die mit zunehmender Komplexität einen breiten Zugriff auf die zugrunde liegenden Maschinenfunktionen bietet, die nicht unbedingt mit anderen Sprachen verfügbar gemacht werden. Verglichen mit C bietet C++ den Vorteil einer vollständig objektorientierten Sprache (reduzierte Entwicklungszeit), die möglicherweise zusätzliche Leistungskosten verursacht. In Bezug auf reale Anwendungen sehe ich diese Sprachen in den folgenden Bereichen:

C

  • Kernel-Level-Software.
  • Hardware-Gerätetreiber
  • Anwendungen, bei denen der Zugriff auf alten, stabilen Code erforderlich ist.

C, C++

  • Anwendungs- oder Serverentwicklung, bei der die Speicherverwaltung genau abgestimmt werden muss (und nicht den üblichen Speicherbereinigungslösungen überlassen werden darf).
  • Entwicklungsumgebungen, die Zugriff auf Bibliotheken erfordern, die nicht gut mit moderneren verwalteten Sprachen kommunizieren können.
  • Obwohl verwaltetes C++ für den Zugriff auf das .NET-Framework verwendet werden kann, handelt es sich nicht um einen nahtlosen Übergang.

C # stellt ein verwaltetes Speichermodell bereit, das wieder eine höhere Abstraktionsebene hinzufügt. Diese Abstraktionsebene erhöht die Benutzerfreundlichkeit und verbessert die Entwicklungszeiten, erschwert jedoch den Zugriff auf APIs auf niedrigerer Ebene und macht spezielle Leistungsanforderungen problematisch. 

Es ist sicherlich möglich, extrem leistungsfähige Software in einer Umgebung mit verwaltetem Speicher zu implementieren, aber das Bewusstsein für die Auswirkungen ist unerlässlich. 

Die Syntax von C # ist sicherlich weniger anspruchsvoll (und fehleranfällig) als C/C++ und hat für den initiierten Programmierer eine flachere Lernkurve.

C #

  • Schnelle Entwicklung von Clientanwendungen.
  • Hochleistungs-Serverentwicklung (zum Beispiel StackOverflow), die vom .NET-Framework profitiert.
  • Anwendungen, die die Vorteile des .NET-Frameworks in der Sprache benötigen, für die es entwickelt wurde.

Johannes Rössel legt fest, dass die Schlüsselwörter für die Verwendung von C # - Zeigern, Unsichere und ungeprüfte Schlüssel die Abstraktionsebene durchbrechen, auf der C # basiert. Ich möchte betonen, dass die Art der Programmierung die Ausnahme zu den meisten C # -Entwicklungsszenarien darstellt und nicht ein grundlegender Bestandteil der Sprache ist (wie dies bei C/C++ der Fall ist).

60
RedBlueThing

Denken Sie daran, dass ich spreche ASFAC++ B . :) Ich habe den wichtigsten Unterscheidungsfaktor an erster Stelle gestellt.

Garbage Collection

Garbage Collection (GC) ist der wichtigste Faktor bei der Unterscheidung zwischen diesen Sprachen.

Während C und C++ mit GC verwendet werden können, handelt es sich um einen nachträglichen Gedanken, der nicht zum Funktionieren gebracht werden kann ( das bekannteste ist hier ) - es muss "konservativ" sein, was bedeutet, dass es kann nicht den gesamten nicht verwendeten Speicher sammeln.

C # wurde von Grund auf für die Arbeit auf einer GC-Plattform entwickelt, wobei auch Standardbibliotheken auf diese Weise entwickelt wurden. Dies ist ein grundlegender Unterschied für die Entwicklerproduktivität, der erlebt werden muss, um geglaubt zu werden.

Unter C/C++ - Benutzern ist die Ansicht weit verbreitet, dass GC mit "schlechter Leistung" gleichgesetzt wird. Aber dies ist eine veraltete Folklore (selbst der Boehm-Sammler unter C/C++ schneidet viel besser ab, als die meisten Leute es erwarten). Die typische Angst besteht in "langen Pausen", in denen das Programm stoppt, damit der GC etwas arbeiten kann. In der Realität treten diese langen Pausen jedoch bei Nicht-GC-Programmen auf, da sie auf einem virtuellen Speichersystem ausgeführt werden, das gelegentlich das Verschieben von Daten zwischen physischem Speicher und Festplatte unterbricht.

Es ist auch weit verbreitet, dass GC durch shared_ptr ersetzt werden kann, aber es kann nicht; Die Ironie ist, dass in einem Multithread-Programm shared_ptr langsamer ist als ein GC-basiertes System.

Es gibt Umgebungen, die so sparsam sind, dass GC nicht praktikabel ist - aber diese werden immer seltener. Handys haben in der Regel GC. Der GC der CLR, auf dem C # normalerweise ausgeführt wird, scheint auf dem neuesten Stand der Technik zu sein.

Seitdem ich C # vor ungefähr 18 Monaten eingeführt habe, habe ich mit einem Profiler mehrere Phasen der reinen Leistungsoptimierung durchlaufen, und der GC ist so effizient, dass er während des Programmbetriebs praktisch unsichtbar ist.

GC ist kein Allheilmittel, es löst nicht alle Programmierprobleme, es räumt nur die Speicherzuordnung wirklich auf. Wenn Sie sehr große Speicherblöcke zuweisen, müssen Sie trotzdem vorsichtig sein, und es ist immer noch möglich, was zu haben In einem ausreichend komplexen Programm ist dies ein Speicherverlust - und dennoch ist GC aufgrund seiner Auswirkung auf die Produktivität ein Allheilmittel!

Undefiniertes Verhalten

C++ basiert auf dem Begriff undefiniertes Verhalten. Das heißt, die Sprachspezifikation definiert das Ergebnis bestimmter eng definierter Verwendungen von Sprachmerkmalen und beschreibt alle anderen Verwendungen als verursachend undefiniertes Verhalten , was im Prinzip bedeutet, dass die Operation ein beliebiges Ergebnis haben kann überhaupt (in der Praxis bedeutet dies schwer zu diagnostizierende Fehler, die eine scheinbar nicht deterministische Datenkorruption beinhalten).

Fast alles an C++ berührt undefiniertes Verhalten. Sogar sehr nette bevorstehende Funktionen wie Lambda-Ausdrücke können auf einfache Weise verwendet werden, um den Stapel zu beschädigen (erfassen Sie ein lokales als Referenz, damit die Lambda-Instanz das lokale überlebt).

C # basiert auf dem Prinzip, dass alle möglichen Operationen ein definiertes Verhalten haben sollten. Das Schlimmste, was passieren kann, ist, dass eine Ausnahme geworfen wird. Dies verändert die Erfahrung der Softwareerstellung grundlegend.

(Es gibt einen unsicheren Modus mit Zeigern und daher undefiniertem Verhalten, von dem jedoch generell abgeraten wird. Betrachten Sie ihn als analog zur eingebetteten Assemblersprache.)

Komplexität

In Bezug auf die Komplexität muss C++ herausgehoben werden, insbesondere wenn wir die sehr bald standardisierte neue Version in Betracht ziehen. C++ tut absolut alles, um sich selbst effektiv zu machen, abgesehen von der Annahme von GC, und als Ergebnis hat es eine beeindruckende Lernkurve. Die Sprachdesigner entschuldigen dies zum großen Teil mit den Worten "Diese Funktionen sind nur für Bibliotheksautoren und nicht für normale Benutzer". Um jedoch in jeder Sprache wirklich effektiv zu sein, müssen Sie Ihren Code als wiederverwendbare Bibliotheken erstellen. Du kannst also nicht entkommen.

Positiv zu vermerken ist, dass C++ so komplex ist, dass es wie ein Spielplatz für Nerds ist! Ich kann Ihnen versichern, dass es Ihnen viel Spaß machen würde, zu lernen, wie alles zusammenpasst. Aber ich kann es nicht ernsthaft als Grundlage für produktive neue Arbeiten (oh, die verschwendeten Jahre ...) auf Mainstream-Plattformen empfehlen.

C hält die Sprache einfach (einfach im Sinne von "der Compiler ist einfach zu schreiben"), aber dies macht die Codierungstechniken geheimnisvoller.

Beachten Sie, dass nicht alle neuen Sprachfunktionen mit zusätzlicher Komplexität einhergehen. Einige Sprachfunktionen werden als "syntaktischer Zucker" bezeichnet, da es sich um Abkürzungen handelt, die der Compiler für Sie erweitert. Dies ist eine gute Möglichkeit, sich viele Verbesserungen von C # in den letzten Jahren vorzustellen. Der Sprachstandard spezifiziert sogar einige Merkmale, indem er die Übersetzung Langschrift erteilt, z. using -Anweisung wird zu try/finally erweitert.

An einem Punkt war es möglich, C++ - Vorlagen auf die gleiche Weise zu denken. Seitdem sind sie jedoch so mächtig geworden, dass sie nun die Grundlage für eine ganz andere Dimension der Sprache bilden, mit einer eigenen begeisterten Benutzergemeinschaft und eigenen Redewendungen .

Bibliotheken

Das Seltsamste an C und C++ ist, dass sie keine austauschbare Standardform einer vorkompilierten Bibliothek haben. Das Integrieren des Codes einer anderen Person in Ihr Projekt ist immer etwas umständlich, und es müssen unklare Entscheidungen darüber getroffen werden, wie Sie darauf verlinken.

Auch die Standardbibliothek ist extrem einfach - C++ verfügt über einen vollständigen Satz von Datenstrukturen und eine Art der Darstellung von Zeichenfolgen (std::string), aber das ist immer noch minimal. Gibt es eine Standardmethode zum Auffinden einer Liste von Dateien in einem Verzeichnis? Erstaunlicherweise nein! Gibt es eine standardmäßige Bibliotheksunterstützung für das Parsen oder Generieren von XML? Was ist mit dem Zugriff auf Datenbanken? Sei ernst! Website-Backend schreiben? Bist du verrückt? usw.

Sie müssen also weiter weg auf die Jagd gehen. Versuchen Sie für XML Xerces . Aber verwendet es std::string, um Zeichenfolgen darzustellen? Natürlich nicht!

Und haben all diese Bibliotheken von Drittanbietern ihre eigenen bizarren Gebräuche, um Klassen und Funktionen zu benennen? Darauf kannst du wetten!

Die Situation in C # könnte unterschiedlicher nicht sein. Die Grundlagen waren von Anfang an vorhanden, sodass alles wunderbar zusammenarbeitet (und da die Grundlagen von der CLR bereitgestellt werden, gibt es sprachübergreifende Unterstützung).

Es ist nicht alles perfekt; Generika sollten von Anfang an vorhanden sein, waren es aber nicht, was bei einigen älteren Bibliotheken eine sichtbare Narbe hinterlässt. In der Regel ist es jedoch trivial, dies extern zu beheben. Außerdem werden einige beliebte Bibliotheken von Java portiert, was nicht so gut passt, wie es zunächst erscheint.

Closures (Anonyme Methoden mit Erfassung lokaler Variablen)

Java und C sind praktisch die letzten verbliebenen Hauptsprachen, denen es an Closures mangelt, und Bibliotheken können mit ihnen viel ordentlicher entworfen und verwendet werden als ohne (dies ist ein Grund, warum portierte Java - Bibliotheken für einen C # -Benutzer manchmal klobig erscheinen).

Das amüsante an C++ ist, dass seine Standardbibliothek so entworfen wurde, als ob Abschlüsse in der Sprache verfügbar wären (Containertypen, <algorithm>, <functional>). Dann vergingen zehn Jahre und jetzt werden sie endlich hinzugefügt! Sie werden eine enorme Auswirkung haben (obwohl sie, wie oben erwähnt, ein unzureichendes Verhalten aufweisen).

C # und JavaScript sind die am häufigsten verwendeten Sprachen, in denen Abschlüsse "idiomatisch festgelegt" sind. (Der Hauptunterschied zwischen diesen Sprachen besteht darin, dass C # statisch typisiert ist, während JavaScript dynamisch typisiert ist.).

Plattformunterstützung

Ich habe dies nur zum Schluss gesagt, weil es diese Sprachen nicht so sehr zu unterscheiden scheint, wie Sie vielleicht denken. Alle diese Sprachen können auf mehreren Betriebssystemen und Maschinenarchitekturen ausgeführt werden. C wird am häufigsten unterstützt, dann C++ und schließlich C # (obwohl C # dank einer Open-Source-Implementierung mit dem Namen Mono auf den meisten wichtigen Plattformen verwendet werden kann).

Meine Erfahrung mit dem Portieren von C++ - Programmen zwischen Windows und verschiedenen Unix-Versionen war unangenehm. Ich habe noch nie versucht, etwas sehr Komplexes in C # nach Mono zu portieren, daher kann ich das nicht kommentieren.

69

C ist das Nackte, eine einfache, saubere Sprache, mit der Sie alles selbst machen können. Es hält nicht deine Hand, es hindert dich nicht daran, dich in den Fuß zu schießen. Aber es hat alles, was Sie brauchen, um das zu tun, was Sie wollen. 

C++ ist C mit hinzugefügten Klassen, und dann eine ganze Reihe weiterer Dinge und noch etwas mehr. Es hält nicht Ihre Hand, aber Sie können Ihre eigene Hand halten, mit Zusatz-GC, RAII und intelligenten Zeigern. Wenn Sie etwas erreichen möchten, besteht die Möglichkeit, dass Sie das Vorlagensystem missbrauchen, um Ihnen eine relativ einfache Syntax zu geben. (mehr dazu mit C++ 0x). Diese Komplexität gibt Ihnen auch die Möglichkeit, aus Versehen ein Dutzend Fälle von sich selbst zu erstellen und sie alle in den Fuß zu schießen.

C # ist der Versuch von Microsoft, C++ und Java zu verbessern. Tonnen von syntaktischen Features, aber nicht in der Nähe der Komplexität von C++. Es wird in einer vollständig verwalteten Umgebung ausgeführt, sodass die Speicherverwaltung für Sie erledigt wird. Es lässt Sie "schmutzig werden" und verwenden Sie unsicheren Code, wenn Sie müssen, aber es ist nicht die Standardeinstellung, und Sie müssen einige Arbeit erledigen, um sich zu erschießen.

14
Eclipse

Meiner Meinung nach ist C # und ASP.NET wäre der beste der drei für die Entwicklung, die webabhängig ist. 

Ich bezweifle, dass jemand neue Web-Apps mehr in C oder C++ schreibt. Es wurde vor 10 Jahren fertiggestellt, und wahrscheinlich wird noch viel älterer Code verwendet, aber er ist nicht besonders gut geeignet, es scheint nicht so viel (laufende) Tool-Unterstützung zu geben, und sie haben wahrscheinlich einen kleinen aktiven Code Community, die Webentwicklung durchführt (außer vielleicht für Webserverentwicklung). Ich habe schon viele Website-C++ - COM-Objekte geschrieben, aber C # ist weitaus produktiver, da es keinen zwingenden Grund gibt, C oder C++ (in diesem Zusammenhang) zu codieren, es sei denn, Sie müssen dies tun. 

Ich schreibe zwar immer noch C++, ist aber normalerweise eine kleine Problemdomäne. z.B. Kommunikation von C # über P/Invoke zu alten C-Style-DLLs - einige Dinge zu tun, die in C # geradezu unbeholfen sind, waren ein Kinderspiel, ein C++ COM-Objekt als Bridge zu erstellen.

Das Schöne an C # ist, dass Sie auch problemlos in Windows- und Konsolen-Apps schreiben und in C # bleiben können. Mit Mono sind Sie auch nicht auf Windows beschränkt (obwohl Sie möglicherweise auf die verwendeten Bibliotheken beschränkt sind).

Trotzdem ist dies alles aus einer Web-Perspektive. Wenn Sie nach eingebetteten Geräten gefragt haben, würde ich C oder C++ sagen. Man könnte behaupten, dass keine davon für die Webentwicklung geeignet ist, aber C #/ASP.NET ist ziemlich glatt, es funktioniert gut, es gibt eine Menge Online-Ressourcen, eine große Community und kostenlose Entwicklungswerkzeuge.

Wenn Sie also aus der realen Perspektive nur eines von C #, C++ und C auswählen, sollten Sie in der Regel bei C # bleiben.

5
Robert Paulson

Ich schätze, Sie möchten aus Ihren anderen Beiträgen eine neue Sprache lernen, um sich neue Fähigkeiten anzueignen. Mein Rat ist, dass die Sprache nicht wirklich wichtig ist. Wichtig ist die Qualität der Community (Ratschläge, aber auch vorhandener Code, aus dem Sie lesen können und von dem Sie lernen können) und die verfügbaren Bibliotheken/Frameworks. In dieser Hinsicht denke ich, dass die "C-Familie" nicht die beste Wahl für Sie ist: Webbibliotheken und Frameworks sind wenige, nicht portabel und nicht großartig, und der Codierstil von Code, den Sie studieren können, variiert sehr und kann Sie sehr verwirren. (Obwohl C meine Lieblingssprache ist)

Ich würde raten, nur C zu lernen und zu versuchen, das Konzept von Zeigern wirklich zu verstehen, und dann auf andere, an das Internet angepasste Sprachen zu wechseln (Python oder Javascript kommt in den Sinn - oder sogar Java). In der C-Familie hat Objective-C meiner Meinung nach die beste Mischung aus Kraft und Einfachheit, ist aber ein Nischenplayer.

4
Colas Nahaboo

C - eine ältere Programmiersprache, die als praktisch beschrieben wird. Als Programmierer müssen Sie das Programm anweisen, alles zu tun. Auch diese Sprache lässt Sie fast alles tun. Es unterstützt keinen objektorientierten Code. Also keine Klassen. 

C++ - eine Erweiterungssprache an sich von C. In C + bedeutet C++ Inkrement 1. Daher ist C++ besser als C. Es erlaubt stark kontrollierten objektorientierten Code. Wieder eine sehr praxisnahe Sprache, die VIEL ins Detail geht. 

Vollständiger objektorientierter Code, der dem Stil von C/C++ - Code ähnelt. Dies ist wirklich näher an Java. C # ist die neueste Version der C-Stilsprachen und eignet sich sehr gut für die Entwicklung von Webanwendungen.

2
Anand Kuma Arya

Verwenden Sie für Rohgeschwindigkeit C. Verwenden Sie C++ für Strom. Verwenden Sie für die .net-Kompatibilität C #. Sie sind alle ziemlich komplex, je nach den Sprachen. C durch jahrzehntelange schrittweise Anhebung, C++ durch Jahre schnellerer Verbesserung und C # durch die Leistungsfähigkeit von Microsoft. 

1
MarkusQ

C ist die Kernsprache, die dem CPU-Maschinencode am nächsten kommt und direkt in diesen übersetzt wird. CPUs folgen Anweisungen, die sich bewegen, hinzufügen, logisch kombinieren, vergleichen, springen, drücken und knallen. C macht genau dies mit einer viel einfacheren Syntax. Wenn Sie die Demontage studieren, können Sie lernen, C-Code zu schreiben, der genauso schnell und kompakt ist wie Assembly. Es ist meine bevorzugte Sprache für 8-Bit-Mikrocontroller mit begrenztem Speicher. Wenn Sie ein großes PC-Programm in C schreiben, werden Sie aufgrund der eingeschränkten Organisation in Schwierigkeiten geraten. Hier wird die objektorientierte Programmierung leistungsfähig. Die Fähigkeit von C++ - und C # -Klassen, Daten und Funktionen zusammen zu enthalten, erzwingt eine Organisation, die eine komplexere Bedienbarkeit über C ermöglicht. C++ war in der Vergangenheit für eine schnelle Verarbeitung unerlässlich, wenn CPUs nur einen Kern hatten. Ich fange jetzt an, C # zu lernen. Seine Klassenstruktur scheint einen höheren Organisationsgrad als C++ zu erzwingen, was letztendlich zu einer schnelleren Entwicklung führen und die gemeinsame Nutzung von Code fördern sollte. C # wird nicht wie VB interpretiert. Es wird teilweise zur Entwicklungszeit kompiliert und dann zur Laufzeit weiter übersetzt, um plattformfreundlicher zu werden.

0
MikeZ