Muss ich C lernen?

8

Ich bin ein Doktorand in Scientific Computing und habe in den letzten Monaten viel Zeit damit verbracht, Python und C ++ richtig zu lernen. Ich habe das Gefühl, dass ich C ++ gut gelernt habe und mit Python tun kann, was ich will, wenn ich ein gutes Nachschlagewerk habe.

Ich kenne MATLAB auch genug, um meine Ideen zu prototypisieren und Lösungen zu finden. (Wenn ich zu gelangweilt bin, um Python zu codieren, ist dies meine erste Wahl).

Ich habe hier mehrfach gelesen, dass man C und C ++ zu einem "C / C ++" zusammenfassen sollte, weil es sich um extrem unterschiedliche Sprachen mit unterschiedlichen Motiven handelt, und ich stimme diesem Standpunkt vollkommen zu.

Ich kann zwar nicht behaupten, C ++ zu "kennen", da ich immer lerne, aber ich denke, ich verstehe die meisten, wie ich es verwenden sollte und wie ich es nicht verwenden sollte. Die erste Sprache, die ich gelernt habe, war C, aber es ist sehr lange her, seit ich sie das letzte Mal benutzt habe. Meine Frage lautet im Wesentlichen:

Vorausgesetzt, ich kenne MATLAB, C ++ und Python; sollte ich Zeit in das Lernen von C investieren? Reichen meine Kenntnisse der genannten 3 Sprachen aus, damit ich programmieren kann?

Meine Forschung ist mehr auf der Seite der numerischen linearen Algebra, aber ich mache auch einige diskrete Ereignissimulationen / stochastische Prozessberatung. Meine Absicht ist es, in der Industrie zu arbeiten (mein Berater schlug vor, C ++ zu lernen, damit ich beschäftigungsfähig bleibe, obwohl er keine persönlichen Sprachpräferenzen hat).

Anfrage
quelle
Der Unterschied zwischen Fortran 60 und Fortran 2003 ist größer als zwischen C99 und C ++ 98. Und zwischen 77 und 2003 ist so ziemlich das gleiche. Trotzdem nennen die Leute sie "nur" Fortran.
Mischa
1
Sie sollten all diese anderen Sprachen werfen und nur Fortran lernen;) Das moderne Fortran hat alles, was Sie für das brauchen, was Sie tun.
Nasser
Unabhängig davon, welche Sprache Sie verwenden, stellen Sie sicher, dass Sie den zu wartenden Code dokumentieren und einige Beispiele und automatisierte Tests enthalten. Wenn Sie das nicht tun, kennen Sie keine Sprache.
cjordan1
@Nasser, außer wenn Sie mit einem Open-Source-Framework in großem Maßstab arbeiten möchten. Lammps, Dealii, Trilinos, MercuryDPM, alle C ++. Ich würde den Leuten raten, alles außer Fortran zu lernen, aber am Ende ist das nur eine Frage der Präferenz.
BlaB

Antworten:

13

Ich werde nur den Vergleich von C mit C ++ ansprechen. Zwar kann alles, was in C geschrieben ist, mit ein paar syntaktischen Nachbesserungen nach C ++ portiert werden, aber die Communitys haben unterschiedliche Werte. Die C-Bibliotheksgemeinschaft legt wie kaum eine andere Wert auf binäre Stabilität. Die Binärstabilität ist für Bibliotheken auf niedriger Ebene von entscheidender Bedeutung, um zu vermeiden, dass den darüber liegenden Schichten ständige Schmerzen zugefügt werden, insbesondere wenn sie mit einem Binärverteilungsmodell und gemeinsam genutzten Bibliotheken verwendet werden. C ist die überwältigende Präferenz für solche Bibliotheken, die nur funktionieren müssen und neue Releases liefern können, ohne die darüber liegenden Ebenen neu zu kompilieren.

Es ist möglich, C ++ - Bibliotheken zu versenden, die auf dieser Ebene arbeiten, aber am Ende müssen Sie "C in C ++ schreiben". Beispielsweise würden Sie niemals eine Strukturdefinition mit privaten oder virtuellen Mitgliedern in einem öffentlichen Header platzieren, Sie würden niemals Vorlagen in einer öffentlichen Schnittstelle verwenden und Sie würden niemals eine API haben, die auf der Vererbung von Klassen basiert, die Datenelemente haben. Diese Einschränkungen sind erforderlich, um Abhängigkeiten genau zu enthalten, damit Sie Ihre Implementierung ändern können, ohne die binäre Schnittstelle zu ändern. C ist aufgrund seines einfacheren Objektmodells und des genau definierten ABI in der Regel viel einfacher aus verschiedenen Sprachen zu binden.

Wenn Sie Code eher auf Anwendungsebene als auf Bibliotheksebene schreiben, ist Ihre binäre Schnittstelle unwichtig, sodass viele dieser Probleme verschwinden. Die Verwendung von C ++ - Sprachfunktionen wie Vererbung und Vorlagen führt immer noch zu einem engeren Code, was zu einer zeitaufwändigeren Neukompilierung führt, wenn das Projekt wächst. Zusätzlich zu umfangreicheren Abhängigkeiten zur Kompilierungszeit erhöht das einfache Kompilieren von C-Code mit einem C ++ - Compiler die Kompilierungszeit erheblich (etwa das Zweifache bei den meisten Toolchains).

Wenn Sie diese Bedenken interessieren oder planen, an Bibliotheken auf niedrigerer Ebene zu arbeiten, kann es sich lohnen, Zeit mit C zu verbringen. Wenn Sie gerne C ++ - Sprachfunktionen verwenden und sich nicht zu sehr um binäre Schnittstellen und die enge Kopplung kümmern, ist dies möglicherweise keine gute Zeitnutzung. Aber denken Sie an C, wenn diese Dinge Sie in Zukunft stören.

Jed Brown
quelle
Es gab so viele tolle Antworten, dass es schwierig war, eine auszuwählen, aber dies war meiner Meinung nach die aussagekräftigste und vollständigste. +1 an alle. Ich habe es sehr genossen, so viele Perspektiven zu lesen. Ich beschloss, C ++ einfach weiter zu perfektionieren und C nach Bedarf zu lernen.
Untersuchung
Der Vollständigkeit halber möchten Sie möglicherweise die Pimpl-Sprache hinzufügen. Dies ist eine Möglichkeit, mit der C ++ - Codierer "Kompilierungsfirewalls" erstellen können, damit sie den Anwendungscode nach den zugrunde liegenden Implementierungsänderungen nicht neu kompilieren müssen.
cjordan1
7

Anstatt "C zu lernen", würde ich vorschlagen, dass Sie an einem Punkt angelangt sind, an dem Sie genug programmiert und mit genügend Programmiersprachen gearbeitet haben, sodass Sie sich stattdessen auf die Verbesserung Ihrer Programmiertechnik und der breiteren Kenntnisse der Informatik konzentrieren sollten. Dann lernen Sie C, wenn und wann Sie es für ein bestimmtes Projekt benötigen.

Erfahrene Programmierer lernen schnell neue Programmiersprachen, wenn dies für bestimmte Projekte erforderlich ist. Sie können dies tun, weil sie wichtige Konzepte verstehen, die von Sprache zu Sprache übersetzt werden. Die Syntax ist kein großes Problem, wenn Sie diese übergeordneten Konzepte beherrschen. Wenn Sie Schüler beobachten, die versuchen, ihre zweite Programmiersprache zu lernen, werden Sie häufig Schwierigkeiten haben, ein neues Konzept zu verstehen, das nicht Teil ihrer ersten Sprache war. Beispielsweise haben Schüler, die mit Fortran beginnen, häufig Probleme mit Zeigern in C. Schüler, die C kennen, haben häufig Probleme mit den objektorientierten Funktionen von C ++ und so weiter.

Brian Borchers
quelle
6

Die Antwort auf diese Frage hängt wirklich davon ab, was Sie wirklich tun.

Als Informatiker, der Hochleistungsrechnen betreibt , würde ich sagen, dass es wichtig ist, die Programmierung in C zu kennen / zu verstehen.

Aber wenn Sie nur tun , Sachen auf Computern, dann Ihr Wissen über C ++ sollte ausreichen , um Sie durch zu bekommen.

Insbesondere wenn Sie sich wirklich für rechnerische Aspekte interessieren, dh für das Schreiben von Algorithmen, die das Beste aus modernen Computern herausholen, müssen Sie sich nicht mit Aspekten auf niedriger Ebene wie Speicherverwaltung, Datenlayouts und SIMD auseinandersetzen Vektorisierung, Parallelität auf Befehlsebene, Parallelität auf gemeinsamem Speicher oder GPU-Computing (CUDA und OpenCL basieren auf C).

Die meisten dieser Dinge können jetzt von Compilern (z. B. für die Speicherverwaltung, Datenlayouts, Vektorisierung) und / oder übergeordneten Abstraktionen (z. B. OpenMP, OpenACC, optimierte Bibliotheken) erledigt werden. Aber nur bis zu einem gewissen Grad. Dinge von Hand zu erledigen ist normalerweise mit mehr Arbeit verbunden, aber die Auszahlung kann eine Größenordnung der Leistung betragen.

Wenn Sie die Details selbst steuern möchten , verwenden Sie normalerweise C, da es "näher am Metall" liegt. Die Frage ist jedoch, ob Sie das wirklich wollen.

Pedro
quelle
1
Wie kann man sagen, dass C ++ weiter vom Metall entfernt ist als C? Was können Sie in C ++ nicht tun, was Sie in C tun können? Und sagen Sie, dass es in C ++ vernachlässigbare nützliche Funktionen für die Berechnung auf niedriger Ebene gibt?
Milind R
@MilindR: Zugegeben, Sie können ein C-Programm mit einem C ++ - Compiler kompilieren, sodass C ++ alles kann, was C tut. Das Problem liegt in den zusätzlichen Funktionen, die C ++ bietet, z. B. polymorphe Objekte, Vorlagen, Pipes usw., die dem tatsächlichen "Metall" nicht gut zugeordnet werden können. Wenn Sie eine dieser Funktionen von C ++ verwenden, verlieren Sie Anweisung für Anweisung die Kontrolle darüber, was Ihr Programm tatsächlich tut. Das ist der Punkt, den ich anstrebte und zu dem ich stehe.
Pedro
Ich stimme polymorphen Objekten zu, aber wie können Vorlagen Sie weiter vom Metall entfernen? Ich denke, Sie beziehen sich hier auf Vererbungshierarchien. Alles, was sie nicht benutzt, ist wahrscheinlich ziemlich nah am Metall.
Milind R
1
@MilindR: Nein. Angenommen, Sie verwenden eine Vorlagenklasse für einen Vektor von floatoder double. Die tatsächlichen Operationen an diesen Vektoren werden auf eine Weise implementiert, die für den einen oder den anderen optimal ist, jedoch niemals für beide. Vererbungshierarchien haben das gleiche Problem wie polymorphe Objekte: Wenn Sie den genauen Typ zur Kompilierungszeit nicht kennen, haben Sie nicht nur einen geringen Aufwand bei der Auswahl der richtigen Funktion, sondern können auch die Zielfunktion nicht inline.
Pedro
Dafür ist die Template-Spezialisierung gedacht. Stimmen Sie zu, dass Sie den Typ zur Kompilierungszeit nicht kennen, was zu Overhead führt.
Milind R
4

Meine Antwort auf diese Frage enthält ein wenig Copy-Paste mit einigen zusätzlichen Details.

Ich arbeite in der Industrie (Hersteller von Vermessungs- und Maschinensteuerungsgeräten) mit schwachen eingebetteten Prozessoren (z. B. Mobiltelefonprozessoren), wo etwa 50% des Rechengrunzens für numerische Berechnungen aufgewendet werden - hauptsächlich für Sensorfusionsarbeiten.

Wir haben einen Mathematiker, der für uns arbeitet und früher in einer HPC-Gruppe gearbeitet hat. Dies ist also einer der merkwürdigen Orte, an denen Sie möglicherweise irgendwann einen Job finden!

In dieser Umgebung, in der Sie mit ziemlicher Sicherheit ein Betriebssystem haben (z. B. Linux, QNX, WinCE), ist C ++ König. Wir verwenden C nur für Kernel-Arbeiten (dh Gerätetreiber) und für tief eingebettete Arbeiten ohne Betriebssystem (8-Bit-Mikros). Wir verwenden C nicht für numerische Arbeiten. In der Tat haben wir keinen FORTRAN-Compiler für unsere Plattform!

Hohe Leistung ist uns wichtig, da wir nur eine 1-Watt-CPU für die Verarbeitung haben. Während wir einige der "glamourösen" Probleme der Parallelität nicht haben, müssen wir uns des Cache und des Gedächtnisses bewusst sein und uns zunehmend der SIMD bewusst sein (denken Sie an NEON ). Darüber hinaus müssen wir im Gegensatz zu HPC die Latenz (dies ist Maschinensteuerung!) Und andere Betriebssystemaspekte wie Zeitplanung und Kontextwechsel genau kennen. Die Speicherzuweisung ist in dieser Umgebung besonders unangenehm, da sie mit ziemlicher Sicherheit einen Kontextwechsel bedeutet (== Latenz und auf einer 400-MHz-CPU zeitaufwändig).

Diese Probleme sind unabhängig von der Wahl der Sprache, daher werde ich der Antwort von @ Pedro, dass C notwendig ist, nicht zustimmen. Schließlich sind Compiler-Intrinsics für SIMD verfügbar, wenn C ++ verwendet wird. Dies bedeutet jedoch, dass Sie sehr vorsichtig sein müssen, welche Funktionen von C ++ Sie verwenden und was sie kosten.

Um die Antwort zu vervollständigen, brauchen Sie kein C. Wir verwenden MATLAB für die Analyse und Python für die Skripterstellung, sodass Ihre beiden anderen Sprachen als C ++ eine gute Wahl sind - zumindest in meiner Branche.

Damien
quelle
3

Es ist gut, C zu kennen, und Sie können viele der OO-Funktionen von C ++, die für die wissenschaftliche Berechnung in C relevant sind, problemlos implementieren (es ist sehr lehrreich, den Quellcode für PETSC zu betrachten, um zu sehen, wie sie funktionieren es).

Auf diese Frage gibt es jedoch keine einheitliche Antwort. Es gibt viele Faktoren bei der Auswahl einer Sprache, darunter auch die Laufzeit. Wie lange Sie Code schreiben, debuggen und profilieren, ist ein weiterer wichtiger Faktor. Am Ende möchten Sie so produktiv wie möglich sein. C zu kennen ist großartig, wenn Sie beabsichtigen, sich auf die Hochleistungsseite der Forschung einzulassen, oder wenn Sie davon ausgehen, dass die Ausführung Ihres Codes extrem lange dauern wird (dh die Laufzeit übertrifft Ihre Codierungs-Workflow-Zeit). Wenn Sie C ++ kennen und diese Dinge kein Problem darstellen, sollten Sie in der Lage sein, C-Code gut genug zu verstehen, um mit denen zu kommunizieren, die ihn verwenden.

Reid.Atcheson
quelle
2
Aber ist C wirklich so schneller als C ++?
Anfrage
2
Programmiersprachen sind nicht a priori schnell oder langsam, es ist der Programmierer, der guten Code schreibt, der seine Wirksamkeit bestimmt. Der Vorteil von C ist, dass es sehr einfach ist und das Schreiben von effizientem Code viel einfacher ist als das Schreiben von effizientem Code in C ++ oder Python (vorausgesetzt, Sie nutzen hier die Sprachfähigkeiten voll aus). Ich habe sehr schnellen C ++ - Code gesehen, der seine vollen Funktionen nutzt, die das Rollen Ihrer eigenen Speicherverwaltung und das Ausführen aller möglichen unangenehmen Dinge mit Überlastung des Bedieners erfordern. Berücksichtigen Sie die Zeit, die zum Schreiben benötigt wird, im Vergleich zu einer äquivalenten C-Version bei gleicher Geschwindigkeit.
Reid.Atcheson
2
@GeoffOxberry Einige der Pakete, die Sie erwähnen, sind wirklich für Flexibilität (in gewissem Umfang) geschrieben, weit mehr als Geschwindigkeit. Diejenigen, die für absolute Geschwindigkeit geschrieben wurden, leiden unter dem schwierigen Debugging, der enormen Kompilierungszeit und den großen Binärdateien, die mit der Verwendung von Vorlagen für viel mehr verbunden sind, als für die Leistung wirklich erforderlich ist. Natürlich können Sie ein "C" -Paket in C ++ schreiben, aber die Community-Werte sind sehr unterschiedlich.
Jed Brown
1
Darüber hinaus meinte ich mit "Hochleistung" nicht unbedingt einfach das Schreiben von Code mit hoher Leistung. Ich meinte auf der Forschungsseite von HPC, mich oft mit vielen Details auf niedrigerer Ebene zu befassen. Diese können mithilfe eines C ++ - Programmierstils verdeckt werden. Dies ist nicht unbedingt eine schlechte Sache, aber es hängt davon ab, was Ihre Ziele sind.
Reid.Atcheson
1
Mit anderen Worten, wenn Sie ein HPC-Forscher sind, ist das Schreiben von Code mit einem anderen Paket, das zufällig schnell ist, in Bezug auf die Forschung nicht wirklich von großem Wert. Die Leute werden wissen wollen, warum Ihr Code schneller ist und warum Ihr Ansatz effektiv ist. Wenn Sie ein Paket zitieren, wird es nicht gekürzt.
Reid.Atcheson
2

Der Wert von c, wie er heutzutage ist, besteht darin, dass Sie gezwungen sind, sich mit der Funktionsweise des Computers auf einer niedrigen Abstraktionsebene (im Vergleich zu beispielsweise Python) vertraut zu machen. Jetzt verfügt c ++ über alle Low-Level-Funktionen von c und könnte genauso gut funktionieren, aber die meisten Leute werden beim Anlehnen von c ++ ermutigt, die Abstraktionen der niedrigsten Ebene zu vermeiden und sich auf die (gut getesteten und debuggten) High-Level-Abstraktionen zu verlassen. Dinge wie die Containerbibliothek, intelligente Zeiger, Polymorphismus und so weiter.

Für die meisten Programmierer ist es sinnvoll, den größten Teil ihrer Zeit damit zu verbringen, in Bereichen mit hoher Abstraktion zu spielen, da sie mehr geistige Zeit und Energie damit verbringen können, zu schreiben, was sie bedeuten, als mit den wählerischen kleinen Details umzugehen, wie Sie dies erreichen.

Die Kosten dieser Einstellung sind ein gewisses Risiko, dass undichte Abstraktionen Sie beißen, wenn Sie es am wenigsten erwarten , aber es trägt mit ziemlicher Sicherheit zur allgemeinen Programmiereffizienz bei.

Wenn Sie also mit dem, was Sie über die Funktionsweise Ihres Computers auf niedriger Ebene wissen, zufrieden sind, können Sie c sicher ausschalten, und selbst wenn Sie dies nicht tun, können Sie einen eingeschränkten Satz von c ++ verwenden, um dasselbe zu erreichen.

dmckee --- Ex-Moderator Kätzchen
quelle
1

Ich habe eine ähnliche Frage einmal bei Stack Overflow beantwortet . Die offensichtliche Antwort ist, alles zu lernen, was Sie können, richtig?

Schauen wir uns also den negativen Standpunkt an. Sie beherrschen bereits drei Sprachen, die ich für die wissenschaftliche Programmierung als wertvoller als C erachten würde. In meiner Beratungsarbeit beim Schreiben wissenschaftlicher Software habe ich MATLAB, Python, FORTRAN und Java verwendet. Ich musste noch nie C oder C ++ verwenden, aber beachten Sie, dass meine gesamte Arbeit an neuen Projekten lag. Ich würde einem Client nicht raten, ein großes Projekt in C / C ++ zu starten, sondern Java oder sogar Scala empfehlen, es sei denn, es gibt einen zwingenden Grund, C / C ++ zu verwenden. Für ein kleineres Projekt würde ich wahrscheinlich mit Python gehen. In Ihrem Fall sieht es so aus, als könnten Sie nach Bedarf mit C umgehen.

Ich würde erwarten, dass es sich mehr auszahlt, mehr über die Bereiche zu lernen, in denen Sie arbeiten werden, als ein Sprachjockey zu sein. Am Ende kommt es auf die Problemlösung an, nicht auf das Werkzeug. Knuths Ansicht über "vorzeitige Optimierung" gilt auch für die Vorbereitung auf eine Karriere.

Glenn
quelle
1

Es ist es wahrscheinlich nicht wert.

C ++ und C besetzen in der Regel die gleichen Nischen in der Computerwissenschaft (möglicherweise sind eingebettete Systeme eine Ausnahme). Früher waren C-Compiler besser (mehr Funktionen vollständig, besser zu optimieren) als C ++ - Compiler, aber nach meinem heutigen Verständnis ist dies nicht mehr der Fall.

Sicher, C ist eine wundervolle Sprache (und ich ziehe sie C ++ vor), und wenn Sie Zeit und Lust haben, würde ich empfehlen, sie zu lernen, aber wenn Sie Zeit haben, sehe ich keinen zwingenden Grund außer "Ich" Sie müssen an einem Projekt arbeiten, das in C "geschrieben wird (und selbst dann wird ein Großteil Ihres C ++ - Wissens übertragen).

Geoff Oxberry
quelle
0

Ich denke, einige C-Kenntnisse sind nützlich, vor allem, um zu lernen, wie man Dinge mit "externer C" -Verknüpfung kompiliert, damit Sie ältere C / Fortran-Bibliotheken (z. B. Lapack) in neue C ++ - Projekte ziehen können. Ich würde nicht viel Zeit in das Erlernen der alten C-Bibliotheken investieren, diese Dinge können nach Bedarf aufgenommen / gegoogelt oder manchmal durch gleichwertige Funktionen in der C ++ - stdlib ersetzt werden.

rchilton1980
quelle