1.基本
Brainfuckを理解するには、0
それぞれによって初期化されるセルの無限配列を想像する必要があります。
...[0][0][0][0][0]...
ブレインファックプログラムが開始すると、任意のセルを指します。
...[0][0][*0*][0][0]...
ポインターを右>
に移動すると、ポインターがセルXからセルX + 1に移動します
...[0][0][0][*0*][0]...
セルの値を増やすと、次のようになり+
ます。
...[0][0][0][*1*][0]...
セルの値をもう一度増やすと +
次のようにます。
...[0][0][0][*2*][0]...
セルの値を減らすと -
次のようになります。
...[0][0][0][*1*][0]...
ポインタを左に動かすと <
に移動すると、セルXからセルX-1にポインタが移動します
...[0][0][*0*][1][0]...
2.入力
文字を読むにはコンマを使います ,
。機能:標準入力から文字を読み取り、その10進ASCIIコードを実際のセルに書き込みます。
ASCIIテーブルを見てください。たとえば、次の10進コード!
は33
、while a
は97
です。
まあ、あなたのBFプログラムのメモリが次のようになっていると想像してみましょう:
...[0][0][*0*][0][0]...
標準入力がを表すとするとa
、コンマ,
演算子を使用する場合、BFが実行するのはa
10進ASCIIコード97
をメモリに読み込むことです。
...[0][0][*97*][0][0]...
一般的にそのように考えたいと思いますが、真実はもう少し複雑です。真実は、BFは文字ではなくバイトを読み取ることです(そのバイトが何であっても)。例を示しましょう:
Linuxでは
$ printf ł
プリント:
ł
特定のポリッシュ文字です。この文字はASCIIエンコードではエンコードされません。この場合は、UTF-8エンコードであるため、コンピュータのメモリで1バイト以上を使用していました。16進ダンプを作成することでそれを証明できます。
$ printf ł | hd
示す:
00000000 c5 82 |..|
ゼロはオフセットされます。82
最初のc5
バイトと2番目のバイトを表しますł
(これらを読み取るため)。|..|
この場合は不可能なグラフィック表現です。
さて、ł
1バイトを読み取るBFプログラムに入力として渡すと、プログラムメモリは次のようになります。
...[0][0][*197*][0][0]...
なんで197
?まあ197
10進数はc5
16進数です。見覚えがある?もちろん。の最初のバイトですł
!
3.出力
文字を印刷するには、ドットを使用します。.
機能は次のとおりです。実際のセル値を10進ASCIIコードのように扱うと仮定して、対応する文字を標準出力に出力します。
まあ、あなたのBFプログラムのメモリが次のようになっていると想像してみましょう:
...[0][0][*97*][0][0]...
ここでドット(。)演算子を使用する場合、BFは何を印刷するかを指定します。
a
そのためa
ASCIIで10進数です97
。
たとえば、次のようなBFプログラム(97プラス2ドット):
++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++ ..
最大97を指すセルの値を増やし、2回出力します。
ああ
4.ループ
BFでは、ループはループ開始[
とループ終了で構成されます]
。条件が実際のセル値であるC / C ++のようなものだと考えることができます。
以下のBFプログラムを見てください。
++[]
++
実際のセル値を2回インクリメントします。
...[0][0][*2*][0][0]...
そしての[]
ようにwhile(2) {}
、それは無限ループです。
このループを無限にしたくないとしましょう。たとえば、次のことができます。
++[-]
したがって、ループがループするたびに、実際のセル値が減少します。実際のセル値が0
ループになると、次のようになります。
...[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)
有限ループのさらに別の例を考えてみましょう:
++[>]
この例は、ループが開始されたセルでループを終了する必要がないことを示しています。
...[0][0][*2*][0][0]... loop starts
...[0][0][2][*0*][0]... after first iteration (loop ends)
ただし、開始した場所を終了することをお勧めします。どうして ?ループが開始した別のセルを終了する場合、セルポインターがどこにあるかは想定できません。正直に言うと、この慣習により、brainfuckは少なくなります。