In dem Buch "The Pragmatic Programmer" (wenn Sie es noch nicht gelesen haben, hören Sie auf, diesen Artikel zu lesen und tun Sie es jetzt!
Auch wenn manche sagen, dass das zu viel Aufwand ist, sind wir uns alle einig, dass es eine gute Idee ist. Eine neue Sprache zu lernen ist nicht so einfach. Wir wollen doch nicht unsere Zeit für etwas aufwenden, das wir in der Praxis vielleicht nie benutzen, oder? Aber vielleicht sollten wir manchmal eine Ausnahme machen und etwas lernen, nur weil es uns Spaß macht? Ich möchte Ihnen die Brainfuck-Sprache vorstellen. Es handelt sich um eine Sprache, die Sie in wenigen Minuten erlernen können, so dass es kein Problem ist, zu viel Zeit umsonst zu investieren. Außerdem kann ich dir versprechen, dass das Lösen eines Problems mit Brainfuck dein Gehirn stimuliert (alle F*cks sind nur ein Bonus ;)). Fangen wir an!Laut Wikipedia:
Brainfuck ist eine esoterische Programmiersprache wurde 1993 von Urban Müller entwickelt. Die Sprache besteht aus nur acht einfachen Befehlen und einem Befehlszeiger. Obwohl sie vollständig Turing-komplett ist, ist sie nicht für den praktischen Gebrauch gedacht, sondern um Programmierer herauszufordern und zu unterhalten.
Überblick über die Sprache
Stellen Sie sich ein unendlich langes Band vor, das aus Zellen besteht, von denen jede mit 0 initialisiert ist. Es gibt auch einen beweglichen Datenzeiger, der zunächst auf die erste Zelle zeigt. Außerdem gibt es zwei Byteströme für die Eingabe und die Ausgabe. Die Befehle werden nacheinander ausgeführt, einer nach dem anderen. Die Maschine hält nach der Ausführung des letzten Befehls an.
Befehl
Was bewirkt es?
>
Datenzeiger auf die nächste Zelle auf der rechten Seite verschieben
<
Datenzeiger auf die nächste Zelle auf der linken Seite verschieben
+
Inkrementierung des Wertes der aktuellen Zelle
–
Wert der aktuellen Zelle dekrementieren
.
Ausgabe des Bytes einer aktuell angezeigten Zelle in ASCII Code
,
ein Byte von stdin lesen und seinen Wert in der aktuellen Zelle speichern
[
wenn die aktuelle Zelle 0 ist, dann Sprung zur passenden Zelle ]
]
Sprung zum passenden [
Alle anderen Zeichen als ><+-.,[] werden ignoriert.
Schauen wir uns ein einfaches Beispiel an:
,+.
Sie wird wie folgt interpretiert:
ein Byte lesen und in der aktuellen Zelle (Zelle0) speichern
Inkrementierung des Wertes der aktuellen Zelle (cell0 = cell0 + 1)
Inhalt der aktuellen Zelle in die Ausgabe schreiben
Als Ergebnis wird ein Zeichen von der Eingabe gelesen und das nächste Zeichen aus der ASCII-Tabelle gedruckt.
Interpreter / Compiler
Bevor wir einige nützliche (?) Programme in Brainfuck schreiben, brauchen wir einen Interpreter oder einen Compiler. AFAIK, gibt es keinen offiziellen, aber das ist kein Problem. Es gibt Dutzende von inoffiziellen im Internet. Ich kann diese beiden empfehlen:
"Hello World!" sollte das erste Programm sein, das wir schreiben, wenn wir eine neue Sprache lernen. Es in Brainfuck zu schreiben ist jedoch etwas schwieriger als in anderen Sprachen. Wir müssen mit etwas Leichterem anfangen... Schreiben wir ein Programm, das einen einzelnen Buchstaben "H" auf dem Bildschirm ausgibt (so spannend :D):
Wie funktioniert das? Es setzt den Wert der aktuellen Zelle auf 72 (in 72er-Schritten) und druckt ihn mit "." (H hat den Code 72 in ASCII) auf den Bildschirm. Jetzt wissen Sie, was wir tun müssen, um "Hello World!" auf dem Bildschirm auszugeben, aber vorher werden wir noch eine kleine Umstrukturierung vornehmen. Das Schreiben all dieser '+' erfordert zu viel Tippen und Zählen. Wir können es kürzer machen, indem wir [ und ] für Schleifen. Um den Wert auf 72 zu setzen, können wir z. B. eine Schleife machen, die den Wert 7 Mal um 10 erhöht. Auf diese Weise erhalten wir 70. Wenn man 2 hinzufügt, wird es 72. Das sieht dann so aus:
++++++++++ # Zelle0 auf 10 setzen
[# Schleife, bis Zelle0 gleich 0 ist
- # Zelle0 verkleinern
> # verschiebt den Datenzeiger nach rechts (Zelle1)
+++++++ # Zelle1 um 7 erhöhen
# verschiebe Datenzeiger nach rechts (Zelle1)
++ # Erhöhung um 2
. # druckt das Ergebnis
Ich habe Kommentare eingefügt, um zu verdeutlichen, wie alles funktioniert. Das gleiche Programm ohne Kommentare:
++++++++++[->+++++++++.
Ist es nicht wunderschön? 🙂
Hallo Welt!
Zurück zu unserem "Hello World!"-Programm. Wir könnten den Wert der ersten Zelle auf 72 (H) setzen und ausdrucken, den Wert der zweiten Zelle auf 101 (e) setzen und ausdrucken, den Wert der dritten Zelle auf 108 setzen und ausdrucken und so weiter. Hier ist die Implementierung dieses Algorithmus:
Ja, nur 1120 Bytes, um "Hello World!" zu drucken... Aber wir können es besser machen! Anstatt für jedes Zeichen eine neue Zelle zu verwenden, können wir auch nur eine verwenden. Um den Buchstaben "e" (101) zu drucken, können wir den Wert in Zelle0 (72) wiederverwenden. Wir können ihn 29 Mal um eins erhöhen (101 - 72). Das Ergebnis ist wie folgt:
Wir haben große Fortschritte gemacht. 377 Bytes anstelle von 1120 Bytes. Aber es gibt noch Raum für Verbesserungen. Ich werde Ihnen einige Ideen geben:
3 (oder mehr) Zellen für Zeichen verwenden, die in ASCII näher beieinander liegen (Kleinbuchstaben, Großbuchstaben, Leerzeichen und Ausrufezeichen)
Schleifen anstelle von Wiederholungen verwenden + und -
Hier ist die Version aus Wikipedia, die diese Ideen verwendet:
Es sind nur 106 Bytes und es wird eine neue Zeile am Ende gedruckt! Erstaunlich.
Umkehrung einer Zeichenkette
Jetzt sind wir bereit, etwas Anspruchsvolleres zu schreiben. Schreiben wir ein Programm, das eine Zeile von der Eingabe liest und sie in umgekehrter Reihenfolge ausgibt. Das erste Problem besteht darin, die Zeichen zu lesen und bei dem Zeichen für die neue Zeile anzuhalten. Erinnern Sie sich, es gibt keine Pause, wenn oder andere ähnliche Aussagen. Wir müssen verwenden [ und ]. Beginnen wir mit einem Programm, das alle Zeichen aus der Eingabe liest und sie in aufeinanderfolgende Zellen einfügt:
,[>,]
Es beginnt mit dem Lesen des ersten Zeichens und wird bis zum letzten fortgesetzt , Betriebsrückkehr 0. Bei einer Implementierung, die etwas anderes zurückgibt als O für EOF (die Sprache schreibt dieses Verhalten nicht vor). Wie können wir also bei dem Zeichen für die neue Zeile anhalten? Hier ist der Trick:
+[++++++++++>,----------]
Wir beginnen mit Zelle0 auf 1 gesetzt, um sicherzustellen, dass unsere Schleife mindestens einmal ausgeführt wird. In einer Schleife erhöhen wir den Wert der aktuellen Zelle um 10, verschieben den Datenzeiger auf die nächste Zelle, lesen ein Zeichen und verringern dessen Wert um 10. Wenn auf diese Weise ein neues Zeilenzeichen (10 in ASCII) gelesen wird, hält das Programm bei der nächsten Iteration an, andernfalls wird der Wert durch Addition von 10 wiederhergestellt.
Nach diesem Schritt sehen unsere Zellen wie folgt aus:
11 C1 C2 C3 0* 0 0
Cn ist das n-te Zeichen der Eingabe, und * ist die aktuelle Position des Datenzeigers. Jetzt müssen wir damit beginnen, den Datenzeiger nach links zu bewegen und alle Zellen zu drucken, bis wir den Wert 11 erreichen. Hier ist mein Ansatz für diese Aufgabe:
Ich möchte Sie ermutigen, es selbst zu analysieren :-).
Zusammenfassung
Als ich über Brainfuck, eine esoterische Programmiersprache, stolperte, tat ich sie zunächst als Spielerei oder Scherz ab. Diese merkwürdige und, wie viele behaupten mögen, verblüffend schwierige Sprache erschien mir als etwas, das nur der Unterhaltung dient. Doch mit der Zeit änderte sich meine Einstellung zu Brainfuck dramatisch.
Die rätselhafte Natur von Brainfuck fordert Sie heraus und zwingt Sie dazu, Ihre Sichtweise zu erweitern Programmiersprachen. Diese esoterische Sprache ermöglicht es Ihnen, die Schönheit und Notwendigkeit von Hochsprachen, an die wir gewöhnt sind, zu schätzen. Sie macht die Bedeutung von Abstraktionen, korrekten Namenskonventionen und einem organisierten Speicherlayout im Bereich der Programmiersprachen deutlich. Dies ist etwas, was Brainfuck mit seinem minimalistischen Design, das nur aus acht einfachen Befehlen besteht, nicht bietet.
Brainfuck ist eine vollständige Turing-Sprache, die die Bedeutung eines klaren, kohärenten Quellcodes noch unterstreicht. Obwohl sie als eine der anspruchsvollsten esoterischen Sprachen für das Schreiben von Programmen gilt, ist sie ironischerweise der Favorit für Anfänger, die einen Brainfuck-Compiler oder einen eigenen Brainfuck-Interpreter erstellen wollen. Der Grund dafür ist die Einfachheit ihres Befehlssatzes und die Tatsache, dass sie kein komplexes Parsing erfordert.
Die Erstellung eines Brainfuck-Programms ist in zweierlei Hinsicht einzigartig. Erstens müssen Sie sich an die Verwendung eines einzigen Speicherzeigers gewöhnen, was Sie zwingt, anders über Ihren Quellcode zu denken. Und zweitens haben Sie die "Null-Option", d. h. die Möglichkeit, die Speicherzelle auf Null zurückzusetzen, eine Funktion, die in anderen formalen Programmiersprachen nicht üblich ist.
Was das Lernen angeht, so gibt es bei Brainfuck mehr, als man auf den ersten Blick sieht. Mit genügend Zeit und der richtigen Einstellung ist es möglich, ein und dasselbe Programm auf vielfältige Weise mit verschiedenen Brainfuck-Codes zu schreiben. In der letzten Hälfte dieser Reise geht es darum, erfinderisch zu sein und neue, kreative Wege zu finden, um die sechs Symbole zu nutzen.
Brainfuck-Interpreter sind zwar minimalistisch, vermitteln aber ein tiefes Verständnis dafür, wie der Code abläuft, was das Programm ausgibt und welche Mechanismen einer vollständigen Turing-Sprache zugrunde liegen. Letztendlich ist Brainfuck nicht nur eine weitere esoterische Programmiersprache. Es ist eine ganz neue Dimension, eine andere Sichtweise darauf, wie wir Programme sehen, verstehen und schreiben.