1. Grundlagen
Um Brainfuck zu verstehen, müssen Sie sich eine unendliche Anzahl von Zellen vorstellen, die von 0
jeder initialisiert wurden .
...[0][0][0][0][0]...
Wenn das Brainfuck-Programm gestartet wird, zeigt es auf eine beliebige Zelle.
...[0][0][*0*][0][0]...
Wenn Sie den Zeiger nach rechts bewegen, bewegen >
Sie den Zeiger von Zelle X zu Zelle X + 1
...[0][0][0][*0*][0]...
Wenn Sie den Zellenwert erhöhen, erhalten +
Sie:
...[0][0][0][*1*][0]...
Wenn Sie den Zellenwert erneut erhöhen, erhalten +
Sie:
...[0][0][0][*2*][0]...
Wenn Sie den Zellenwert verringern, erhalten -
Sie:
...[0][0][0][*1*][0]...
Wenn Sie den Zeiger nach links bewegen, bewegen <
Sie den Zeiger von Zelle X zu Zelle X-1
...[0][0][*0*][1][0]...
2. 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 !
is 33
, while a
is 97
.
Stellen wir uns vor, Ihr BF-Programmspeicher sieht folgendermaßen aus:
...[0][0][*0*][0][0]...
Angenommen, die Standardeingabe steht für a
: Wenn Sie einen Kommaoperator verwenden ,
, liest BF a
dezimalen ASCII-Code 97
in den Speicher:
...[0][0][*97*][0][0]...
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
$ printf ł
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:
$ printf ł | hd
welche Shows:
00000000 c5 82 |..|
Nullen werden versetzt. 82
ist das erste und c5
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:
...[0][0][*197*][0][0]...
Warum 197
? Nun, 197
Dezimalzahl ist c5
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:
...[0][0][*97*][0][0]...
Wenn Sie jetzt den Punkt (.) -Operator verwenden, druckt BF Folgendes:
ein
Weil a
Dezimalcode in ASCII ist 97
.
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.
aa
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:
...[0][0][*2*][0][0]...
Und []
ist wie while(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:
...[0][0][*2*][0][0]... loop starts
...[0][0][*1*][0][0]... after first iteration
...[0][0][*0*][0][0]... after second iteration (loop ends)
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:
...[0][0][*2*][0][0]... loop starts
...[0][0][2][*0*][0]... after first iteration (loop ends)
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.