Ich glaube, C ist eine gute Sprache, um die Prinzipien hinter dem Programmieren zu lernen. Was können Sie in niedrigeren Sprachen lernen, die von höheren Sprachen wie Ruby "magisch" sind?
Ich glaube, C ist eine gute Sprache, um die Prinzipien hinter dem Programmieren zu lernen. Was können Sie in niedrigeren Sprachen lernen, die von höheren Sprachen wie Ruby "magisch" sind?
Antworten:
In C gibt es keine Prinzipien im allgemeinen abstrakten Sinne der Informatik, die nicht auch in höheren Sprachen vorhanden sind. Die gesamte Informatik läuft auf Algorithmen hinaus, und alle Algorithmen können in jeder Sprache implementiert werden, die so vollständig wie C ist.
Der Unterschied, den C von höheren Sprachen unterscheidet, ähnelt dem Unterschied, den Maschinencode von C unterscheidet: Die Beziehung der Maschine zum Code.
Wenn Sie Code in Hochsprachen schreiben, kümmern Sie sich (im Allgemeinen) nicht darum, wie Ihr Code mit dem Computer interagiert. Die virtuelle Maschine, die die Sprache für sich selbst definiert, verbirgt viele dieser Aspekte der Codeausführung.
In C steht die Interaktion Ihres Programms mit dem Speicher im Vordergrund. Es ist mehr als nur so, dass Sie die Verwendung des Heaps verwalten müssen, es umfasst die Interaktion Ihres Codes mit dem Stapel und wie sich der bloße Zugriff Ihres Codes auf den Speicher auf das Verhalten und die Leistung Ihres Codes auswirkt - nicht einmal auf die Reihenfolge der Speicherzugriffe kann Ihrer Aufmerksamkeit entgehen, da das Lesen des falschen Speichers zur falschen Zeit die Leistung effektiv beeinträchtigen kann.
In höheren Sprachen sind diese Dinge einfach nicht so offensichtlich. Der Speicher wird ohne Ihr Wissen und manchmal ohne Ihre Aufforderung zugewiesen und freigegeben. Meistens liegt dies einfach außerhalb Ihrer Kontrolle. Das Wann, Wo, Wie und Warum der meisten Speicherzuordnungen ist Ihnen einfach verborgen.
In der anderen Richtung bringt das Schreiben von Maschinencode oder Assembler-Code noch mehr Details in den Vordergrund: Fast nichts bleibt außerhalb Ihres Zuständigkeitsbereichs, und Ihr Code muss unter Berücksichtigung jeder Zuordnung, jeder Ressource, jedes übergebenen Datenelements geschrieben werden durch die Register der CPU - Wissen, das so weit von Hochsprachen entfernt ist, dass es geheimnisvoll ist.
Ich weiß, dass C eine gute Sprache ist, um die Prinzipien hinter dem Programmieren zu lernen.
Ich stimme dir nicht zu. In C fehlen zu viele Funktionen, um die Prinzipien der Programmierung zu erlernen. Die Funktionen von C zum Erstellen von Abstraktionen sind schrecklich, und die Abstraktion ist eines der Schlüsselprinzipien der Programmierung.
Wenn Sie lernen möchten, wie Hardware funktioniert und daher ein gewisses mechanisches Verständnis für die Maschine besteht, sollten Sie den Maschinencode, auch als Befehlssatzarchitektur bezeichnet, lernen und auch die Cache-Konstruktion moderner CPUs studieren. Beachten Sie, dass ich keine Assemblersprache empfehle. Verstehen Sie einfach die Hardwareanweisungen, damit Sie verstehen, was ein Compiler generiert.
Wenn Sie Programmierprinzipien lernen möchten, verwenden Sie eine moderne Sprache wie Java, C # oder Swift oder eine der Dutzenden anderen wie Rust. Studieren Sie auch die verschiedenen Arten von Programmierparadigmen, einschließlich funktionaler.
Die meisten Programmiersprachen werden als abstrakte Maschinen beschrieben. Anschließend werden sie mithilfe von Tools wie Compilern, Linkern, Assemblern, Interpreten, statischen Analysatoren, Zwischensprachen und Hardware implementiert , die zusammen ein Ergebnis liefern, das mindestens das gesamte erwartete Verhalten der abstrakten Maschine berücksichtigt, das von einem Programm beobachtet wird .
C ist keine Ausnahme von der obigen Regel. Es wird als abstrakte Maschine beschrieben, die keine Ahnung von Ihrer tatsächlichen Hardware hat.
Wenn Leute sagen, dass C Ihnen beibringt, wie Ihr Computer tatsächlich funktioniert, bedeutet dies normalerweise, dass C Ihnen beibringt, wie C funktioniert. Da C in der Systemprogrammierung so weit verbreitet ist, ist es verständlich, dass viele Leute anfangen, es mit dem Computer selbst zu verwechseln. Und ich persönlich würde sogar sagen, dass es oft wichtiger ist zu wissen, wie C funktioniert, als zu wissen, wie der Computer selbst funktioniert.
Aber noch, C und die Computer sind verschiedene Dinge. Die eigentliche Hardware ist tatsächlich kompliziert - so, dass die C-Spezifikation wie ein Kinderbuch gelesen wird. Wenn Sie daran interessiert sind, wie Ihre Hardware funktioniert, können Sie jederzeit ein Handbuch nachschlagen und Code in einem Assembler schreiben. Oder Sie können jederzeit etwas über digitale Schaltkreise lernen, um selbst Hardware zu entwerfen. (Zumindest werden Sie zu schätzen wissen, wie hoch C ist.)
Okay, das Erlernen von Hardware beinhaltet andere Dinge als C. Aber kann C Programmierern heute noch etwas anderes beibringen?
Ich denke es kommt darauf an.
Seien Sie nicht zu schnell, um eine dieser Möglichkeiten zu wählen. Ich schreibe seit vielen Jahren Code und habe immer noch keine Ahnung, welche die richtige Antwort ist oder ob die richtige Antwort nur eine der beiden ist oder ob es zu diesem Thema eine richtige Antwort gibt.
Ich bin ein wenig geneigt zu glauben, dass Sie wahrscheinlich beide Optionen irgendwann anwenden sollten, lose in der Reihenfolge, in der ich sie beschrieben habe. Aber ich denke nicht, dass dies wirklich eine technische Angelegenheit ist, ich denke, dass es eine hauptsächlich lehrreiche ist. Jeder Mensch scheint auf deutlich unterschiedliche Weise zu lernen.
Wenn Sie die obige Frage zumindest mit der von mir vorgeschlagenen zweiten Option beantwortet haben, haben Sie bereits einige Antworten: Alles, was in höheren Sprachen gelernt werden kann, kann besser gelernt werden, indem Sie es in C oder at neu erfinden am wenigsten durch Zugabe von C zu der Mischung erweitert.
Aber unabhängig von Ihrer Antwort gibt es sicherlich einige Dinge, die Sie fast ausschließlich von C (und vielleicht einer Handvoll anderer Sprachen) lernen können.
C ist historisch wichtig. Es ist ein Meilenstein, den Sie sich ansehen und schätzen können, woher wir kommen, und vielleicht ein bisschen mehr Kontext darüber bekommen, wohin wir gehen. Sie können erkennen, warum bestimmte Einschränkungen bestehen, und Sie können erkennen, dass bestimmte Einschränkungen aufgehoben wurden.
C kann Ihnen beibringen, in unsicheren Umgebungen zu arbeiten. Mit anderen Worten, es kann Sie trainieren, auf Ihren Rücken zu achten, wenn die Sprache (jede Sprache) dies aus irgendeinem Grund nicht für Sie tun kann oder will. Dies kann Sie selbst in sicheren Umgebungen zu einem besseren Programmierer machen, da Sie selbst weniger Fehler verursachen und die Sicherheit vorübergehend deaktivieren können, um die zusätzliche Geschwindigkeit Ihres ansonsten sicheren Programms zu verringern (z. B. Verwendung von Zeigern) in C #) in den Fällen, in denen Sicherheit mit Laufzeitkosten verbunden ist.
C kann Ihnen beibringen, dass für jedes Objekt Speicheranforderungen, ein Speicherlayout, die Tatsache, dass über einen endlichen Adressraum auf Speicher zugegriffen werden kann, usw. vorliegen. Während andere Sprachen Ihre Aufmerksamkeit in diesen Angelegenheiten nicht benötigen, gibt es einige Fälle, in denen eine erworbene Intuition Ihnen helfen kann, fundiertere Entscheidungen zu treffen.
C kann Sie über das Build-System über die Details von Verknüpfungs- und Objektdateien sowie über andere Feinheiten informieren. Auf diese Weise erhalten Sie nützliche praktische Informationen darüber, wie ein nativ kompiliertes Programm häufig vom Quellcode zur Ausführung übergeht.
C kann Ihren Geist dazu bringen, auf neuartige Weise durch das Konzept des undefinierten Verhaltens zu denken. Undefiniertes Verhalten ist eines meiner Lieblingskonzepte in der Softwareentwicklung, da die Untersuchung seiner Auswirkungen auf nicht-klassische Compiler eine einzigartige mentale Übung ist, die Sie in anderen Sprachen nicht ganz finden können. Sie müssen jedoch Versuch und Irrtum ablehnen und die Sprache sorgfältig und absichtlich lernen, bevor Sie diesen Aspekt vollständig verstehen können.
Aber die vielleicht wichtigste Erkenntnis, die C Ihnen als kleine Sprache gewähren kann, ist die Idee, dass die gesamte Programmierung auf Daten und Operationen hinausläuft . Vielleicht möchten Sie Dinge als modulare Klassen mit Hierarchien und Schnittstellen zum virtuellen Versand oder als elegante unveränderliche Werte betrachten, die mit rein mathematischen Funktionen bearbeitet werden. Und das ist alles in Ordnung - aber C wird Sie daran erinnern, dass alles nur Daten + Operationen sind . Es ist eine nützliche Denkweise, weil es Ihnen ermöglicht, einige mentale Barrieren abzubauen.
Der Grund, warum C gut zum Lernen ist, ist nicht, dass es irgendwelche Prinzipien lehrt . Es lehrt Sie, wie die Dinge funktionieren .
C kann mit einem dieser guten alten Autos aus den 70ern oder 80ern verglichen werden, die nur zum Fahren gebaut wurden. Sie können sie zerreißen, Schraube für Schraube und verstehen, wie jedes Teil funktioniert und wie es mit den anderen Teilen zusammenarbeitet, die Sie in die Hände nehmen können, um sie anzusehen. Wenn Sie alle Teile verstanden haben, haben Sie ein sehr klares Bild davon, wie das Ganze funktioniert.
Moderne Sprachen ähneln eher einem modernen Auto, bei dem der Motor im Grunde genommen eine Black Box ist, viel zu komplex, um von einem durchschnittlichen Autobesitzer verstanden zu werden. Diese Autos können viel, zum Teufel, in diesen Tagen lernen sie aktiv, selbstständig zu fahren. Und mit dieser Komplexität und diesem Komfort wurde die Benutzeroberfläche viel weiter von dem entfernt, was tatsächlich im Motor vor sich geht.
Wenn Sie das Programmieren in C lernen, kommen Sie mit vielen Schrauben und Muttern in Kontakt, aus denen ein Computer besteht. Auf diese Weise können Sie ein Verständnis für die Maschine selbst entwickeln. So können Sie beispielsweise verstehen, warum es keine gute Idee ist, eine lange Zeichenfolge wie diese zu erstellen:
java.lang.String result = "";
for(int i = 0; i < components.size; i++) {
result = result + components[i];
};
(Ich hoffe, dies ist korrektes Java, ich habe es eine Weile nicht mehr verwendet ...) Aus diesem Codebeispiel geht nicht hervor, warum die Schleife eine quadratische Komplexität aufweist. Dies ist jedoch der Fall, und es ist der Grund, warum dieser Code zum Stillstand kommt, wenn Sie einige Millionen kleiner Komponenten verketten müssen. Der erfahrene C-Programmierer weiß sofort, wo das Problem liegt, und wird es wahrscheinlich vermeiden, solchen Code überhaupt zu schreiben.
for(int i = 0; i < strlen(s); i++)
in C schreiben , hat die Schleife auch eine quadratische Komplexität und ist genauso offensichtlich wie in Ihrem Java-Beispiel ;-)
Es gibt bessere Sprachen als C, um "die Prinzipien hinter dem Programmieren" zu lernen, insbesondere theoretische Prinzipien, aber C kann gut sein, um einige praktische, wichtige Dinge über das Handwerk zu lernen. Die Antwort von greyfade ist sicherlich richtig, aber meiner Meinung nach können Sie von C mehr lernen, als wie Sie das Gedächtnis selbst verwalten. Beispielsweise,
wie man Programme mit einer vollständigen Fehlerbehandlung ohne Ausnahmen erstellt
wie man eine Struktur in einem Programm erstellt, ohne Sprachunterstützung für die Objektorientierung zu haben
Umgang mit Daten ohne Datenstrukturen wie dynamische Listen, Wörterbücher oder eine nützliche Zeichenfolgenabstraktion
So vermeiden Sie häufige Fehler wie Array-Überläufe, auch wenn der Compiler oder die Laufzeitumgebung Sie nicht automatisch warnt
Erstellen generischer Lösungen ohne Sprachunterstützung für Vorlagen oder Generika
und habe ich schon erwähnt, dass Sie lernen können, wie Sie das Gedächtnis selbst verwalten können? ;-);
Wenn Sie C lernen, lernen Sie außerdem, woher die syntaktischen Gemeinsamkeiten von C ++, Java, C # und Objective C stammen.
Im Jahr 2005 schrieb Joel Spolsky eine Empfehlung für das Erlernen von C vor jeder anderen höheren Sprache. Seine Argumente sind
"Sie werden niemals in der Lage sein, effizienten Code in höheren Sprachen zu erstellen."
"Sie werden nie in der Lage sein, an Compilern und Betriebssystemen zu arbeiten, die zu den besten Programmieraufgaben überhaupt gehören."
"Es wird Ihnen nie vertraut, Architekturen für Großprojekte zu erstellen."
"Wenn Sie nicht erklären können, warum Sie while(*s++ = *t++);
einen String kopieren, oder wenn das für Sie nicht das Natürlichste auf der Welt ist, dann programmieren Sie auf Aberglauben
Natürlich ist das, was er geschrieben hat, sicherlich umstritten, aber meiner Meinung nach sind viele seiner Argumente noch heute gültig.
Die beiden grundlegenden Abstraktionen des Rechnens sind Turing-Maschinen und Lambda-Kalkül, und C ist eine Möglichkeit, mit der Turing-Maschinen-Sicht der Berechnung zu experimentieren: Meistens eine Folge von Aktionen auf niedriger Ebene, aus denen ein wünschenswertes Ergebnis hervorgeht. Sie müssen jedoch berücksichtigen, dass C über ein eigenes Rechenmodell verfügt. Wenn Sie also C lernen, lernen Sie die Details der abstrakten C-Maschine kennen, die sich stark von den tatsächlichen Architekturen unterscheidet. Eines der ersten Dinge, die mir in C beigebracht wurden, war, niemals zu versuchen, den Compiler durch "clevere" Tricks zu überlisten, und es scheint, dass der Trend zu immer mehr Optimierungen bei Compilern geht. Wie in anderen Hochsprachen verstehen Compiler beim Schreiben in C, was Sie auf der abstrakten C-Maschine erwarten, und sorgen dafür, dass dies auf der eigentlichen Hardware geschieht.
Ich meine also, dass das Lernen von C nicht unbedingt ein gutes Bild davon gibt, was tatsächlich in der Hardware passiert. "C ist nah an der Maschine" sollte als "näher als die meisten höheren Sprachen" verstanden werden. Das direkte Erlernen der Softwarearchitektur ist lohnender, wenn Sie ein genaueres Bild davon erhalten möchten, wie es funktioniert.
Auf der anderen Seite kann das Lernen von C Sie mit Systemprogrammierung, Low-Level-Typen, Zeigern und insbesondere der Speicherzuweisung vertraut machen. Ich habe keinen Vorteil darin, Algorithmen und Datenstrukturen in C und nicht in anderen Sprachen zu lernen.
Es ist eine sehr offene Frage, die möglicherweise keine schlüssige Antwort liefert. Sie können so ziemlich alles in jeder Sprache lernen, vorausgesetzt, Sie verstehen die Interna des Sprachrahmens. C zwingt Sie, niedrigere Details zu verstehen, da es hauptsächlich zum Schreiben eines Betriebssystems entwickelt wurde. Selbst nach so vielen Jahren ist es immer noch eine der am häufigsten verwendeten Sprachen, vor allem dank eingebetteter Systeme und Open Source-Projekten. Die Frage ist also, was Sie lernen möchten? Und in welchem Bereich?