Warum kategorisieren einige Programmierer C, Python, C ++ anders? - in Bezug auf das Niveau

15

Ich nehme an einem Einführungskurs in Python teil und der Kursleiter sagt, dass Python eine Hochsprache und C und C ++ Niedrigsprachen sind. Es ist nur verwirrend. Ich dachte, dass C, C ++, Python, Java usw. alles Hochsprachen sind.

Ich habe bei stackoverflow Fragen zu C, C ++ usw. gelesen und sie scheinen alle auf diese Sprachen als hoch zu verweisen. Es scheint mir, dass einige Programmierer diese Begriffe synonym verwenden.

atheistlearner
quelle
1
Wie viele andere Dinge ist ein hohes oder niedriges Niveau eine Vereinfachung - nützlich für das Verständnis, aber möglicherweise irreführend, wenn Sie vergessen, dass es sich um eine Vereinfachung handelt. Welches Niveau ist sicherlich relativ, wie andere gesagt haben. Aber es muss nicht unbedingt eine Linie sein - es gibt verschiedene Richtungen, in die Sie abstrahieren können (z. B. verschiedene Paradigmen). Nur weil Sie sich weiter von der Maschinenabstraktion entfernen, müssen Sie sich nicht unbedingt einer für Ihre Anwendung geeigneten Abstraktion zuwenden.
Steve314
Auch der Ausgangspunkt kann variieren. Zum Beispiel ist die Lambda-Berechnung nach IMO eine sehr niedrige Abstraktionsebene - viel Abstraktion in der Maschine, aber es ist eine sehr einfache Abstraktion, die als Ausgangspunkt für die Erstellung von Abstraktionen durch funktionale Sprachen dient. In jedem Fall ist die Lambda-Berechnung wahrscheinlich nicht näher an der idealen Abstraktion für eine bestimmte Anwendung als der Maschinencode.
Steve314

Antworten:

31

High Level und Low Level sind relative Begriffe, so dass sich die Nutzung im Laufe der Zeit geändert hat. In den 70er Jahren machte UNIX Wellen, weil sich herausstellte, dass ein Betriebssystem hauptsächlich in einer Hochsprache geschrieben werden konnte: C. Zu der Zeit galt C im Gegensatz zu Assembler als Hochsprache.

Heutzutage wird C als einfache Sprache betrachtet, da weder die Sprache noch die Standardbibliotheken eine der Brotdatenstrukturen wie Vektoren, Wörterbücher, Iteratoren usw. bereitstellen. Sie können alle diese Strukturen in einem C-Programm haben, aber Sie werden sie am Ende selbst schreiben. Python, Java usw. sind relativ zu C auf hohem Niveau, da viele dieser Standarddatenstrukturen in die Sprache integriert sind oder Teil der Standardbibliotheken sind. Wenn diese sofort einsatzbereit sind, ist es einfacher, auf einer abstrakteren Ebene zu programmieren.

C ist im zweiten Sinne niedrig: Es ermöglicht die direkte Manipulation der Computerhardware (mindestens so direkt, wie es das Betriebssystem zulässt). Die gängigsten Implementierungen von Python, Java usw. sind mindestens einen Schritt weiter von der Hardware entfernt, da sie in einer VM ausgeführt werden. Wenn Sie die Hardware von Python aus manipulieren möchten, müssen Sie eine Erweiterung für die Python-VM schreiben, normalerweise in C oder C ++.

C ++ ist ein seltsamer Fall. Es bietet als Teil der Standardbibliothek jede Menge an ansprechender Datenstrukturen, ermöglicht jedoch auch eine einfache Manipulation der Hardware.

Charles E. Grant
quelle
3
C ++ ist kein sonderbarer Fall, IMO - es ist einfach eine gemischte Sprache. Der Grad der Abstraktion hängt davon ab, welche Funktionen Sie verwenden.
Steve314
1
@ Steve314: Ja und nein: Bei der Abstraktion werden normalerweise Informationen ausgeblendet, dh eine Sprache oder Bibliothek ist wie eine Blackbox, die eine Schnittstelle bietet, und niemand möchte wissen, was sich in der Blackbox befindet. C ++ ist etwas seltsam, da es Konstrukte höherer Ebenen bietet, aber den Programmierer nicht daran hindert, auf ihre Repräsentation zuzugreifen und sie zu beschädigen. C ++ ist die einzige mir bekannte Sprache, die keine verschiedenen Abstraktionsebenen isoliert (aber möglicherweise gibt es andere Sprachen, die ich nicht kenne).
Giorgio
1
@Giorgio - C ++ ermöglicht es Ihnen , sich zu verstecken jede Implementierung Detail - zum Beispiel machen es Teil der privaten Interna einer Klasse so die einzige offizielle Weg , um es über die öffentliche Schnittstelle der Klasse zu bedienen ist . Natürlich können Sie die Regeln brechen und Ihren Speicher nach Belieben verschlüsseln. In der Praxis können Sie dies jedoch in jeder Sprache tun, die die Entwicklung realer Anwendungen unterstützt.
Steve314
@ Giorgio - Nehmen Sie zum Beispiel Haskell. "Unsicher" bedeutet in diesem Fall in der Regel nicht referenziell transparent (wie in unsafePerformIO). Es gibt IORefTypen, aber es gibt kein Äquivalent von reinterpret_castmir und kein Äquivalent von Zeigerarithmetik. Das heißt aber nicht, dass es sicher ist, dass sich keine Menschen mit Erinnerungen an etwas aufhalten. Um eine praktische Sprache zu sein, muss Haskell mit realen Betriebssystemen und Bibliotheken kommunizieren. Es hat eine "Fremdfunktionsschnittstelle". Wenn ich es wirklich untergraben will, muss ich nur das FFI verwenden, um die primitiven Subversion-Funktionen zu schreiben.
Steve314
@ Giorgio - Natürlich fällt es mir schwer , die Werte zu finden, die ich im Speicher beschädigen möchte, aber dies kann auch in C ++ zutreffen, je nachdem, wie gut ich sie ausgeblendet habe. Zum Beispiel könnte ich einen PIMPL verwenden . Wenn ich dann nur den Objektcode und den Header für die Bibliothek bereitstelle, die versteht, worauf dies hindeutet, muss der potenzielle Subversive diesen Objektcode rückentwickeln, um herauszufinden, was und wie zu unterwandern ist.
Steve314
8

Stellen Sie sich das in einer Skala vor, die von LOW-Level-Sprachen bis zu HIGH-Level-Sprachen reicht. Wenn eine Sprache von NIEDRIG auf HOCH aufsteigt, wird die spezifische Schnittstelle zum Computer durch die Sprache immer stärker abstrahiert.

LOW-Level-Sprachen sind so geschrieben, dass sie den Computer explizit steuern - denken Sie an Maschinencode und Assembly-Code.

HIGH-Level-Sprachen versuchen, die kleinsten Details (insbesondere Speicherzuweisung und Speicherfreigabe) zu abstrahieren. Die Idee ist, eine "natürlichere" Schnittstelle für die Programmierung bereitzustellen und dem Programmierer hoffentlich zu ermöglichen, sich auf Design und Produktion zu konzentrieren.

Heutzutage wird C als LOW-Level-Sprache angesehen. Es hat immer noch einige bedeutende Abstraktionen von Maschinencode und Assembler-Code, ist also technisch "höher" als diese. Es bietet jedoch weiterhin eine direkte Speicheradressierung und keine Speicherbereinigung. Das sind also Details, für die ein Programmierer entwerfen muss.

Vergleichen Sie dies mit anderen Sprachen wie Python, Ruby oder Haskell und Sie haben eine viel unübersichtlichere Oberfläche. Diese Sprachen haben große Codebibliotheken, die den größten Teil des Computerbefehls abstrahieren. Haben Sie sich jemals gefragt, was mit einer Variablen in Python passiert, wenn Sie den lokalen Bereich einer Funktion verlassen oder sie löschen? Wahrscheinlich nicht richtig? Und das liegt daran, dass Sie in einer Hochsprache nicht müssen! Sie kümmern sich um die Speicherbelegung / Freigabe für Sie.

Hochsprachen haben den Vorteil der Funktion. Sie erlauben uns, frei (und sicher!) Zu entwerfen und zu entwickeln.

LOW-Level-Sprachen haben in den meisten Fällen den Vorteil der Geschwindigkeit. Die Interpretation von HIGH-Level-Code ist mit Kosten verbunden. Außerdem ist es ziemlich cool, etwas in "Computersprache" zu schreiben.

Hoffe das hilft

Nick Burns
quelle
5

High-Level vs. Low-Level ist keine Schwarz-Weiß-Sache, sondern eine kontinuierliche Skala. Die Begriffe beschreiben, wie nah eine Programmiersprache an der Hardware ist. Je höher die Stufe, desto mehr abstrahiert sie die Hardware.

Die unterste Ebene ist offensichtlich der binäre Maschinencode - dies ist die genaue Darstellung, die das Betriebssystem lädt und an die CPU weiterleitet. Assembly ist die erste Abstraktionsebene, die darauf aufbaut: Anstelle von Binärcode werden Mnemos geschrieben, von Menschen lesbare symbolische Codes, die binäre Maschinenbefehle darstellen. Dies ist, was Menschen für die Systemprogrammierung vor UNIX verwendet.

C ist der nächste Schritt in der Abstraktionskette, bei dem allgemeine Muster in Flusssteuerungskonstrukte gebündelt und maschinenspezifische Anweisungen in plattformunabhängige Syntax abstrahiert werden. Diese letzten Abstraktionen waren einer der Hauptfaktoren, die UNIX sowohl revolutionär als auch äußerst erfolgreich machten Dies bedeutete, dass derselbe Code für jede Plattform ohne größere Änderungen kompiliert werden konnte.

C ++ fügt eine weitere Abstraktionsebene hinzu: Es fügt Klassen hinzu (Zusammenfassung von vtables und Kontext, die in eine OOP-Syntax übergehen) newund delete(Bündelung der Speicherzuordnung und Variableninitialisierung in einem einzigen Konstrukt), Typprüfung zur Kompilierungszeit und Vorlagen (typsichere Kompilierungszeit) Metaprogrammierung) und eine Reihe von Syntaxkomforten zur Kompilierungszeit wie Namespaces, Funktions- und Operatorüberladung usw.

Python geht einen weiteren großen Schritt von der Hardware weg. C ++ gibt dem Programmierer weiterhin die volle Kontrolle über die Speicherzuweisung und ermöglicht die direkte Manipulation des Arbeitsspeichers. Python übernimmt die Speicherverwaltung für Sie. Anstatt Ihren Code mit Anweisungen für alle systemeigenen Maschinen zu kompilieren, wird er auf einer virtuellen Maschine ausgeführt. Dies ist mit einer Leistungsbeeinträchtigung verbunden (die manchmal schwerwiegend sein kann, aber normalerweise kein Grund zur Sorge ist), ermöglicht aber auch nette Dinge, die in C ++ schwierig und in C unerträglich schwierig wären, wie das Manipulieren von Funktionen und Klassen beim Ausführen Abrufen der Namen beliebiger Objekte zur Laufzeit, Instanziieren von Klassen nach Namen zur Laufzeit, Patchen von Affen usw. usw.

Wenn Leute also Sprachen in "High Level" und "Low Level" unterteilen, ziehen sie irgendwo eine willkürliche Linie, und diese Linie ist nicht immer dieselbe. 1970 lag die Grenze zwischen Assembler und C (das Ableiten von plattformspezifischen Maschinenanweisungen war der entscheidende Faktor); 1987 war es vielleicht irgendwo zwischen C und C ++; Heute kann es zwischen C ++ und Java liegen (wobei die automatische Speicherverwaltung der entscheidende Faktor ist).

Kurz gesagt: High-Level-Ness ist eine gleitende Skala, und für die drei Sprachen, die Sie erwähnen, ist es C <C ++ <Python.

tdammers
quelle
Ich würde sagen, High-Level vs Low-Level ist nicht eine Skala, sondern zwei separate Skalen. Low-Level-Ness bezieht sich darauf, wie gut sich eine Sprache auf das Maschinenverhalten bezieht, während High-Level-Ness sich auf die Fähigkeit bezieht, eine Abstraktion bereitzustellen. C # ist mehr eine Hochsprache als C99, aber es ist auch niedriger als die Sprache, die durch den C-Standard definiert ist, da das Verhalten z Die Zeit wird in C # definiert, jedoch nicht in C99.
Supercat
3

Die Grenze zwischen der "niedrigen" und der "hohen" Sprache verschiebt sich von Zeit zu Zeit.
Zum Beispiel:
In den Tagen von UNIX war C eine Hochsprache.
Heutzutage hat C nicht die Strukturen wie die Abbildungstypen (Wörterbücher), Iteratoren usw., die die heutigen Hochsprachen wie Python haben. Die Linie hat sich also verschoben, und C ist jetzt in die Gruppe der unteren Ebenen gefallen.

Low-Level-Sprachen:
Diese Sprachen sind "nah" an dem, was die Maschine ausführen kann (die unterste Ebene ist: Assembler-Code!).
Wenn der Programmierer mit diesen Sprachen arbeitet, muss er sich Gedanken über Dinge auf der untersten Ebene wie Speicherverwaltung machen. Sie sind in diesem Sinne der Hardware nahe, mit der Sie direkt arbeiten müssen.

High-Level-Sprachen:
Diese Sprachen entziehen sich der Hardware, da sie Dinge wie den Speicher selbst verwalten. Wenn Sie mit diesen Sprachen arbeiten, ist der Speicher ein Faktor (offensichtlich), aber Sie arbeiten nicht direkt mit der Hardware. Stattdessen schafft die Sprache dies und hält Sie von der niedrigeren Hardware-Oberfläche fern (möglicherweise höher).

Pradyunsg
quelle