Jemand hat mir das geschickt und behauptet, es sei eine Hallo-Welt in Brainfuck (und ich hoffe es ...)
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
Ich kenne die Grundlagen, die es funktioniert, indem man einen Zeiger bewegt und Sachen inkrementiert und dekrementiert ...
Trotzdem möchte ich wissen, wie es eigentlich funktioniert. Wie druckt es überhaupt etwas auf dem Bildschirm? Wie verschlüsselt es den Text? Ich verstehe gar nichts...
brainfuck
esoteric-languages
Speeder
quelle
quelle
Antworten:
1. Grundlagen
Um Brainfuck zu verstehen, müssen Sie sich eine unendliche Anzahl von Zellen vorstellen, die von
0
jeder initialisiert wurden .Wenn das Brainfuck-Programm gestartet wird, zeigt es auf eine beliebige Zelle.
Wenn Sie den Zeiger nach rechts bewegen, bewegen
>
Sie den Zeiger von Zelle X zu Zelle X + 1Wenn Sie den Zellenwert erhöhen, erhalten
+
Sie:Wenn Sie den Zellenwert erneut erhöhen, erhalten
+
Sie:Wenn Sie den Zellenwert verringern, erhalten
-
Sie:Wenn Sie den Zeiger nach links bewegen, bewegen
<
Sie den Zeiger von Zelle X zu Zelle X-12. Eingabe
Um Zeichen zu lesen, verwenden Sie Komma
,
. Was es tut, ist: Lesen Sie das Zeichen von der Standardeingabe und schreiben Sie seinen dezimalen ASCII-Code in die eigentliche Zelle.Schauen Sie sich die ASCII-Tabelle an . Zum Beispiel ist der Dezimalcode von
!
is33
, whilea
is97
.Stellen wir uns vor, Ihr BF-Programmspeicher sieht folgendermaßen aus:
Angenommen, die Standardeingabe steht für
a
: Wenn Sie einen Kommaoperator verwenden,
, liest BFa
dezimalen ASCII-Code97
in den Speicher:Sie möchten im Allgemeinen so denken, aber die Wahrheit ist etwas komplexer. Die Wahrheit ist, dass BF kein Zeichen, sondern ein Byte liest (was auch immer dieses Byte ist). Lassen Sie mich Ihnen ein Beispiel zeigen:
Unter Linux
Drucke:
Das ist spezifischer polnischer Charakter. Dieses Zeichen wird nicht durch ASCII-Codierung codiert. In diesem Fall handelt es sich um eine UTF-8-Codierung, sodass früher mehr als ein Byte im Computerspeicher benötigt wurde. Wir können es beweisen, indem wir einen hexadezimalen Dump erstellen:
welche Shows:
Nullen werden versetzt.
82
ist das erste undc5
das zweite Byteł
(in der Reihenfolge, in der wir sie lesen werden).|..|
ist eine grafische Darstellung, die in diesem Fall nicht möglich ist.Wenn Sie
ł
als Eingabe an Ihr BF-Programm übergeben, das ein einzelnes Byte liest, sieht der Programmspeicher folgendermaßen aus:Warum
197
? Nun,197
Dezimalzahl istc5
hexadezimal. Scheint vertraut ? Natürlich. Es ist das erste Byte vonł
!3. Ausgabe
So drucken Charakter Verwendung der Punkt
.
Was sie tut , ist: Angenommen , wir tatsächlichen Zellwert wie dezimal ASCII - Code behandeln, drucken Zeichen auf die Standardausgabe entspricht.Stellen wir uns vor, Ihr BF-Programmspeicher sieht folgendermaßen aus:
Wenn Sie jetzt den Punkt (.) -Operator verwenden, druckt BF Folgendes:
Weil
a
Dezimalcode in ASCII ist97
.So zum Beispiel ein BF-Programm wie dieses (97 plus 2 Punkte):
Erhöht den Wert der Zelle, auf die sie zeigt, auf bis zu 97 und druckt sie zweimal aus.
4. Schleifen
In BF besteht die Schleife aus Schleifenanfang
[
und Schleifenende]
. Sie können denken, es ist wie in C / C ++, wo die Bedingung der tatsächliche Zellenwert ist.Schauen Sie sich das BF-Programm unten an:
++
erhöht den tatsächlichen Zellenwert zweimal:Und
[]
ist wiewhile(2) {}
, so ist es Endlosschleife.Angenommen, wir möchten nicht, dass diese Schleife unendlich ist. Wir können zum Beispiel tun:
Jedes Mal, wenn eine Schleife eine Schleife durchläuft, wird der tatsächliche Zellenwert verringert. Sobald der tatsächliche Zellenwert erreicht ist
0
, endet die Schleife:Betrachten wir noch ein weiteres Beispiel für eine endliche Schleife:
Dieses Beispiel zeigt, dass wir die Schleife nicht in der Zelle beenden müssen, in der die Schleife begonnen hat:
Es ist jedoch eine gute Praxis, dort zu enden, wo wir begonnen haben. Warum ? Denn wenn die Schleife eine andere Zelle beendet, die sie gestartet hat, können wir nicht davon ausgehen, wo sich der Zellenzeiger befindet. Um ehrlich zu sein, macht diese Praxis Brainfuck weniger Brainfuck.
quelle
Wikipedia hat eine kommentierte Version des Codes.
Zur Beantwortung Ihrer Fragen, die
,
und.
sind Zeichen für I / O verwendet. Der Text ist ASCII.Der Wikipedia- Artikel geht auch etwas tiefer.
quelle
,
und.
für E / A verwendet wird, ähnlich wie C-Drucke mitputchar
. Es ist ein Implementierungsdetail, das vom Compiler verarbeitet wird.Um die Frage zu beantworten, woher es weiß, was gedruckt werden soll, habe ich die Berechnung der ASCII-Werte rechts neben dem Code hinzugefügt, in dem gedruckt wird:
quelle
Brainfuck wie sein Name. Es verwendet nur 8 Zeichen
> [ . ] , - +
, was es zur am schnellsten zu erlernenden Programmiersprache macht , aber am schwierigsten zu implementieren und zu verstehen. … Und bringt dich dazu, dein Gehirn zu ficken.Es speichert Werte im Array: [72] [101] [108] [111]
Lassen Sie den Zeiger zunächst auf Zelle 1 des Arrays zeigen:
>
Bewegen Sie den Zeiger um 1 nach rechts<
Bewegen Sie den Zeiger um 1 nach links+
Erhöhen Sie den Wert der Zelle um 1-
Erhöhen Sie den Wert des Elements um 1.
Druckwert der aktuellen Zelle.,
Eingabe in die aktuelle Zelle vornehmen.[ ]
Schleife, +++ [-] Zähler mit 3 Zählungen, da 3 '+' vor ihm liegen, und - die Zählvariable um 1 Wert dekrementiert.Die in Zellen gespeicherten Werte sind ASCII-Werte:
Beziehen Sie sich also auf das obige Array: [72] [101] [108] [108] [111] Wenn Sie mit den ASCII-Werten übereinstimmen, werden Sie feststellen, dass es sich um Hello writtern handelt
Glückwunsch! Sie haben die Syntax von BF gelernt
--- Etwas mehr ---
Lassen Sie uns unser erstes Programm machen, dh Hello World . Danach können Sie Ihren Namen in dieser Sprache schreiben.
in Stücke brechen:
Erstellt ein Array von 4 Zellen (Anzahl von>) und setzt einen Zähler von 10 wie: —-puedo code—-
Da der Zählerwert in Zelle 0 gespeichert ist und> in Zelle 1 verschoben wird, wird sein Wert um + 7 aktualisiert.> In Zelle 2 wird 10 auf den vorherigen Wert erhöht und so weiter.
<<<
kehre zu Zelle 0 zurück und dekrementiere ihren Wert um 1daher haben wir nach Abschluss der Schleife ein Array: [70,100,30,10]
Bewegt sich zum ersten Element und erhöht seinen Wert um 2 (zwei '+') und druckt dann das Zeichen ('.') mit diesem ASCII-Wert. dh zum Beispiel in Python: chr (70 + 2) # druckt 'H'
bewegt sich zum 2. Zelleninkrement 1 auf seinen Wert 100 + 1 und druckt ('.') seinen Wert, dh chr (101) chr (101) #prints 'e', jetzt gibt es kein> oder <im nächsten Stück, so dass es den aktuellen Wert annimmt des neuesten Elements und nur inkrementieren
Das neueste Element = 101 ist daher 101 + 7 und druckt es zweimal (da es zwei '..' gibt). chr (108) #prints l zweimal kann als verwendet werden
——— Wo wird es verwendet? ——-
Es ist nur eine Scherzsprache, die Programmierer herausfordert und praktisch nirgendwo verwendet wird.
quelle
Alle Antworten sind gründlich, aber es fehlt ihnen ein kleines Detail: Drucken. Beim Aufbau Ihres Brainfuck-Übersetzers berücksichtigen Sie auch den Charakter. So
.
sieht eine Druckaussage in Brainfuck aus. Ihr Brainfuck-Übersetzer sollte also immer dann, wenn er auf ein.
Zeichen trifft, das aktuell angezeigte Byte drucken.Beispiel:
Angenommen , Sie haben ->
char *ptr = [0] [0] [0] [97] [0]
... wenn dies eine Gehirnfick Anweisung lautet:>>>.
Ihr Zeiger sollte 3 Plätze nach rechts Landung in verschoben werden:[97]
, jetzt*ptr = 97
, nachdem ich , dass Ihr Übersetzer ein begegnet.
, sollte es dann Aufrufoder eine äquivalente Druckanweisung zum Drucken des aktuell angezeigten Bytes, das den Wert 97 hat und der Buchstabe
a
wird dann auf dem gedrucktstd_output
.quelle
Ich denke, Sie fragen sich, woher Brainfuck weiß, was mit dem gesamten Code zu tun ist. Es gibt einen Parser, der in einer höheren Sprache wie Python geschrieben ist, um zu interpretieren, was ein Punkt oder was ein Additionszeichen im Code bedeutet.
Der Parser liest Ihren Code also Zeile für Zeile und sagt, ok, es gibt ein> Symbol, also muss ich den Speicherort vorrücken. Der Code lautet einfach, wenn (Inhalt in diesem Speicherort) ==>, memlocation = + memlocation, was ist geschrieben in einer höheren Sprache, ähnlich wenn (Inhalt im Speicherort) == ".", dann drucken (Inhalt des Speicherorts).
Hoffe das klärt es auf. tc
quelle