Muss ich C lernen, um zu verstehen, wie ein Computer funktioniert?

Published on October 19, 2018

Muss ich C lernen, um zu verstehen, wie ein Computer funktioniert?

Ursprünglicher Autor: Steve Klabnik
  • Übersetzung
Ich habe oft gehört, dass die Leute, um zu verstehen, wie ein Computer funktioniert, vorschlagen, C zu studieren. Ist das eine gute Idee? Sind sie sicher? Präsentieren Sie sofort die Schlussfolgerungen des Artikels, um absolute Klarheit zu schaffen:

  • C ist nicht "wie ein Computer funktioniert".
  • Ich glaube nicht, dass die meisten Leute buchstäblich sprechen, also spielt es keine Rolle.
  • Das Verstehen des Kontexts bedeutet, dass das Erlernen von C aus diesem Grund abhängig von Ihren Zielen immer noch sinnvoll sein kann.

Ich plane, zwei weitere Artikel mit einer detaillierteren Erläuterung der Schlussfolgerungen zu schreiben, aber das ist bereits genug. Ich werde hier Links hinzufügen, wenn Artikel herauskommen.

Ich habe oft von Leuten wie diesen gehört:

Wenn Sie C studieren, können Sie verstehen, wie Computer funktionieren.

Ich denke nicht, dass die Idee anfangs falsch ist, aber sie hat einige Vorbehalte. Wenn Sie sie im Auge behalten, kann dies eine praktikable Strategie sein, um neue und wichtige Dinge zu lernen. Ich sehe jedoch selten Leute, die diese Vorbehalte ausführlich diskutieren. Deshalb schreibe ich diesen Artikel, um meiner Meinung nach einen sehr notwendigen Kontext zu bieten. Ich hoffe, es hilft, es herauszufinden.

Bevor wir wirklich anfangen, möchte ich noch eins sagen: Wenn du C lernen willst, dann lerne! Lernen ist großartig. Das Studium von C ist für mein Verständnis der Computertechnologie und meine Karriere sehr wichtig geworden. Wenn Sie diese Sprache und ihren Platz in der Geschichte einer Programmiersprache studieren, werden Sie zu einem besseren Programmierer. Du brauchst keine Entschuldigung. Lerne Dinge nur um zu lernen. Dieser Artikel soll als Leitfaden dienen, um die Wahrheit zu verstehen. Es wird nicht diskutiert, ob C untersucht werden soll oder nicht.

Zuallererst, wer diese Idee generell empfohlen hat. Wenn Sie versuchen, „zu lernen, wie Computer funktionieren“, verstehen Sie dies natürlich derzeit nicht. Welche Programmierer verstehen nicht, wie Computer funktionieren? Ich habe dieses Gefühl im Grunde genommen von Leuten gesehen, die hauptsächlich dynamisch getippte Skriptsprachen wie Ruby, Python oder JavaScript verwenden. Sie sollen „nicht wissen, wie Computer funktionieren“, weil diese Sprachen in einer virtuellen Maschine funktionieren, in der nur die Semantik der virtuellen Maschine von Bedeutung ist. Letztendlich besteht die ganze Idee einer virtuellen Maschine darin, Portabilität bereitzustellen. Das Ziel ist nicht von der Hardware abhängig, auf der die VM ausgeführt wird.

Es gibt nur ein Problem: C auch in einer virtuellen Maschine ausgeführt wird .

Abstrakte Maschine C


Aus der C99-Spezifikation , Abschnitt 5.1.2.3, „Programmausführung“:

Semantische Beschreibungen in dieser Internationalen Norm beschreiben das Verhalten einer abstrakten Maschine, bei der Optimierungsprobleme keine Bedeutung haben.

Meiner Meinung nach ist es am wichtigsten, dies zu verstehen, wenn man C studiert. Die Sprache beschreibt nicht "wie ein Computer funktioniert", sondern wie "abstrakte Maschine C" funktioniert. Alles andere Wichtige folgt aus diesem Konzept.

Noch ein Hinweis: Hier habe ich C99 gewählt, was nicht der neueste C-Standard ist. Nun, MSVC hat ... interessante Unterstützung für die C-Sprache , und heute bin ich ein Windows-Benutzer. Ja, können Sie laufen clangund gccunter Windows. Es gibt keinen großen Unterschied zwischen C89, C99 und C11 in Bezug auf das, worüber wir sprechen. Irgendwann muss man sich entscheiden. Die hier erwähnte Version enthält einige Änderungen an der ursprünglichen Spezifikation.

Vielleicht haben Sie in Gesprächen über C einen anderen Satz gehört: "C ist ein portabler Assembler." Wenn Sie über diesen Ausdruck nachdenken, werden Sie verstehen, dass C nicht der Arbeit eines Computers entsprechen kann, wenn dies zutrifft: Es gibt viele verschiedene Computer mit unterschiedlicher Architektur. Wenn C wie ein Assembler ist, der auf verschiedenen Computern mit verschiedenen Architekturen ausgeführt wird, kann er nicht genau wie jeder dieser Computer gleichzeitig funktionieren. Es muss die Details verbergen, sonst ist es nicht tragbar!

Ich denke jedoch, dass diese Tatsache keine Rolle spielt, da es unwahrscheinlich ist, dass die Leute wörtlich "C ist, wie ein Computer funktioniert" meinen. Bevor wir darauf zurückkommen, sprechen wir über die abstrakte Maschine C und warum viele Menschen diesen Aspekt von C nicht verstehen.

Retreat: Warum irren sich die Leute?


Ich kann nur über meine Erfahrungen sprechen, auch wenn dies mit Sicherheit kein Einzelfall ist.

Ich habe GW-BASIC gelernt, dann C, dann C ++, dann Java. Ich habe von Java gehört, bevor ich 1999, vier Jahre nach seinem Erscheinen, damit begonnen habe, darüber zu schreiben. Das Marketing war zu dieser Zeit aktiv gegen Java und C ++, es konzentrierte sich auf die JVM als Plattform und auf die Tatsache, dass das Maschinenmodell es von C ++ unterscheidet und daher C. Sun Microsystems nicht mehr existiert, aber der Spiegel der Pressemitteilung erinnert uns daran:

Java-Anwendungen sind plattformunabhängig. Sie müssen lediglich eine Java Virtual Machine auf jede Plattform portieren. Es fungiert als Interpreter zwischen dem Computer des Benutzers und der Java-Anwendung. Eine in der Java-Umgebung geschriebene Anwendung kann überall ausgeführt werden, sodass keine Anwendungen auf mehrere Plattformen migriert werden müssen.

Das Hauptmotto lautete "Einmal schreiben, überall laufen". Aus diesen beiden Sätzen wurde, wie ich (und viele andere) Java verstand und wie es sich von C ++ unterscheidet. Java hat einen Interpreter, eine Java Virtual Machine. In C ++ gibt es keine virtuelle Maschine.

Mit solch einem leistungsstarken Marketing ist eine „virtuelle Maschine“ in den Köpfen vieler Menschen zum Synonym für „eine große Laufzeitumgebung und / oder einen großen Interpreter“ geworden. Sprachen ohne diese Funktion waren zu stark an einen bestimmten Computer gebunden und mussten portiert werden, da sie nicht wirklich plattformunabhängig sind. Der Hauptgrund für die Existenz von Java war die Änderung dieses C ++ - Fehlers.

"Runtime", "Virtual Machine" und "Abstract Machine" sind unterschiedliche Wörter für dasselbe grundlegende Konzept. Seitdem haben sie jedoch unterschiedliche Konnotationen erhalten, da diese Ideen nur unwesentlich voneinander abweichen.

Ich persönlich glaube, dass dieses Marketing von 1995 der Grund ist, warum Programmierer immer noch die Natur von C missverstehen.

Also ist diese Aussage falsch? Warum gibt Sun Microsystems Millionen und Abermillionen von Dollar aus, um für Lügen zu werben? Wenn C auch auf einer abstrakten Maschine basiert, die plattformübergreifende Portabilität bietet, warum sollte Java verwendet werden? Ich denke, dass dies der Schlüssel ist, um zu verstehen, was die Leute wirklich meinen, wenn sie sagen, dass C die Funktionsweise eines Computers ist.

Was meinen die Leute wirklich?


Obwohl C im Kontext einer virtuellen Maschine funktioniert, unterscheidet es sich dennoch erheblich von Java-ähnlichen Sprachen. Sonne hat nicht gelogen. Um zu verstehen, müssen Sie die Geschichte von C kennen.

1969 schrieb Bell Labs ein Computerbetriebssystem in Assemblersprache. 1970 wurde es UNIX getauft. Mit der Zeit kauften Bell Labs immer mehr neue Computer, einschließlich des PDP-11.

Als es an der Zeit war, Unix auf den PDP-11 zu portieren, entschieden sie sich für eine höhere Sprache, was zu dieser Zeit eine ziemlich radikale Idee war. Stellen Sie sich vor, dass ich Ihnen heute sage: "Ich werde ein Betriebssystem in Java schreiben" - Sie werden wahrscheinlich lachen, obwohl die Idee realisierbar ist.. Die Situation (nach meinem Verständnis habe ich damals nicht gelebt) war ungefähr die gleiche. Es wurde eine Sprache mit dem Namen B in Betracht gezogen, die jedoch einige der Funktionen des PDP-11 nicht unterstützte. Sie erstellten einen Nachfolger mit dem Namen "C", da dies der nächste Buchstabe im Alphabet war.

Sprache "A" war nicht; B hat BCPL (Basic Combined Programming Language) erfolgreich abgeschlossen.

1972 wurde der erste C-Compiler auf den PDP-11 geschrieben und gleichzeitig wurde UNIX in C umgeschrieben. Anfangs wurde nicht an Portabilität gedacht, sondern an C, sodass die C-Compiler auf andere Systeme portiert wurden.

1978 erschien die erste Ausgabe des Buches "Programming Language C". Das Buch, das nach den Namen seiner Autoren liebevoll als „K & R“ bezeichnet wurde, entsprach in keiner Weise der Spezifikation, sondern beschrieb die Sprache in einigen Einzelheiten, weshalb andere auch versuchten, Compiler C zu schreiben. Später wird diese „Version“ als „K & R C“ bezeichnet.

Mit der Verbreitung von UNIX und C wurden beide auf viele Computer portiert. In den 70er und 80er Jahren wuchs ihre Hardware-Basis stetig. Genau wie C erstellt wurde, verwendeten viele Compiler Spracherweiterungen, da B nicht alle Funktionen des PDP-11 unterstützte. Da es nur K & R gab, keine Spezifikation, wurde dies als akzeptabel angesehen, solange die Erweiterungen nah genug waren. 1983 verursachte das Fehlen jeglicher Standardisierung Probleme, weshalb ANSI eine Gruppe bildete, um die Spezifikation zu erstellen. 1989 kam der Standard C89 heraus, der manchmal als "ANSI C" bezeichnet wird.

In Spezifikation C wurde versucht, diese verschiedenen Implementierungen auf unterschiedlicher Hardware zu vereinheitlichen. Somit ist die abstrakte Maschine C eine Art minimal mögliche Spezifikation, die es ermöglichen würde, dass derselbe Code auf allen Plattformen gleich funktioniert. C-Implementierungen wurden kompiliert, nicht interpretiert, es gab also keinen Interpreter, also keine "VM" im Sinne von 1995. C-Programme werden jedoch auf diesen abstrakten, nicht vorhandenen Computer geschrieben, und der Code wird dann in einen Assembler konvertiert, der für den Computer spezifisch ist, auf dem das Programm ausgeführt wird. Sie konnten sich nicht auf bestimmte Details verlassen, um portablen Code in C zu schreiben. Dies macht das Schreiben von portablem C sehr schwierig, da Sie möglicherweise eine plattformspezifische Annahme getroffen haben, als Sie die ursprüngliche Version Ihres Codes geschrieben haben.

Dies lässt sich am besten anhand eines Beispiels veranschaulichen. Einer der Hauptdatentypen in der Sprache C ist chardas Wort "Zeichen". Die abstrakte C-Maschine bestimmt jedoch nicht, wie viele Bits enthalten sein sollen char. Nun ja, aber nicht nach Zahlen. es bestimmt die Größe CHAR_BIT, die eine Konstante ist. Abschnitt 5.2.4.2.1 der Spezifikation:

Die unten angegebenen Werte müssen durch konstante Ausdrücke ersetzt werden, die sich für Vorverarbeitungsrichtlinien eignen oder in diesen verwendet werden. #ifWerte in konkreten Implementierungen müssen mindestens so groß sein (absoluter Wert) wie die hier angegebenen Werte mit dem gleichen Vorzeichen.

CHAR_BIT: 8

Mit anderen Worten, Sie wissen, was charmindestens 8 Bits sind, aber Implementierungen können mehr sein. Um richtig die „abstrakte Maschine C» kodieren, wie die Größe in der Verarbeitung charverwendet werden soll CHAR_BITstatt 8. Dies ist jedoch keine Art von Interpreterfunktion, wie wir es von virtuellen Maschinen her kennen. Dies ist eine Eigenschaft davon, wie der Compiler den Quellcode in Maschinencode übersetzt.

Ja, es gibt Systeme, in denen dies CHAR_BITnicht der Fall ist 8.

Daher ist diese „abstrakte Maschine“, obwohl technisch dieselbe Idee wie die Java Virtual Machine, eher ein Kompilierungskonstrukt zum Verwalten von Compilern beim Erstellen von Assembly-Code als eine Art Test zur Laufzeit oder in Eigenschaften. Der äquivalente Typ in Java ist, dass es byteimmer 8 Bits sind und die JVM-Implementierung die Aufgabe hat, was auf Plattformen mit mehr Bytes zu tun ist. (Nicht sicher, ob die JVM auf einer dieser Plattformen funktioniert, aber so sollte es funktionieren). Die abstrakte Maschine C wird als Minimal-Wrapper für verschiedene „Hardware“ erstellt und nicht als eine Art Solid-Tissue-Plattform, die in Software für Ihren Code geschrieben wurde.

Also, obwohl Sun technisch nicht richtig war, bedeuten sie in der Praxis nicht so viel, was sie wörtlich sagen, und dass siegemein - richtig. Dasselbe gilt für den Satz "Lernen Sie C, um die Funktionsweise von Computern zu verstehen."

Lernen Sie C, um die Funktionsweise von Computern besser zu verstehen


Was meinen die Leute wirklich ? Im Kontext von "Sollte ein Ruberist C studieren, um zu verstehen, wie Computer funktionieren" lautet der Rat, "auf die Eisenebene" abzulehnen. Das heißt, Sie müssen nicht nur verstehen, wie das Programm in der virtuellen Maschine funktioniert, sondern auch, wie die Kombination aus Programm und VM im Kontext der Maschine selbst funktioniert.

Wenn Sie sich mit C befassen, erhalten Sie weitere Informationen, da die abstrakte Maschine sowohl der Hardware als auch den Abstraktionen der Betriebssysteme viel näher ist. Die Sprache C unterscheidet sich stark von den Hochsprachen, so dass das Lernen eine Menge lehren kann.

Es ist jedoch wichtig, sich daran zu erinnern, dass C im Wesentlichen eine Abstraktion ist.Hardware und Abstraktionen sind nicht perfekt. Achten Sie darauf, was C ausmacht oder wie es mit der Maschine selbst funktioniert. Wenn Sie zu tief gehen, werden Sie definitiv auf diese Unterschiede stoßen, die Probleme verursachen können. Die meisten Bildungsressourcen für C, besonders heute, wenn das Gerät homogenere immer wird die Idee fördern, nur weil ein Computer funktioniert. Daher kann es für einen Studenten schwierig sein zu verstehen, was unter der Haube vor sich geht und welche Abstraktion C liefert.

In dieser Diskussion haben wir nicht einmal andere Themen angesprochen. Beispielsweise ist die Hardware aufgrund der enormen Popularität von C homogener geworden, da sie tendenziell zur Semantik der abstrakten Maschine C tendiert. Wenn sich Ihre Architektur zu stark von der Semantik von C unterscheidet, können C-Programme viel langsamer ausgeführt werden als andere. und die Geschwindigkeit der Hardware wird häufig durch Tests in der Sprache C gemessen. Dieser Artikel ist bereits ziemlich lang ...

Aus diesem Grund denke ich, dass eine genauere Version dieser Aussage lautet: " Wenn Sie C studieren, erfahren Sie mehr über die Funktionsweise von Computern." Ich denke wirklich, dass eine grobe Kenntnis von C für viele Programmierer nützlich ist, auch wenn sie kein C schreiben. Wenn Sie C kennenlernen, erhalten Sie auch eine Vorstellung von der Geschichte unserer Branche.

Es gibt andere Möglichkeiten, dieses Thema zu untersuchen. C ist von Natur aus nicht dafür gedacht, Computer zu studieren, aber es ist eine gute Option.

In der Programmierung gibt es so viel zu lernen. Ich wünsche Ihnen viel Erfolg auf diesem Weg.