【第1回】Brainfuckを実装しながら学ぶC++【Brainfuckとは】
IT技術
第1回目~Brainfuckを実装しながらC++学ぼう
本連載では、「Brainfuck」の特性を理解しながら、実際に Brainfuck インタプリタを作成していきたいと思います!
実は、Brainfuck を理解するということは、C/C++ でつまずきがちな「ポインタの概念を理解する」ということにつながります。
つまり、Brainfuck インタプリタの実装は、プログラミング言語を深く学習するのに、もってこいの題材だということ。
今まで、C/C++ を避けていたプログラマの皆さん!
これを機に、C/C++ をマスターしながら、Brainfuck もマスターしていきましょう!
Brainfuckとは
Brainfuck (またはBrainf*ck) は、実用性を無視した、難読プログラミング言語 (通称 Esolang ) に分類されます。
単なるユーモアプログラミング言語でありながら、チューリング完全 (≒なんでもプログラミング可能) な言語でもあるのです。
例えば、「Hello, world!」と出力させたければ、Brainfuck では以下のように記述します。
1+++++++++[->++++++++>+++++++++++>+++++<<<]>.>++.+++++++..+++.>-.
2------------.<++++++++.--------.+++.------.--------.>+.
見た目は、何をしているのか、さっぱりですね…。
にもかかわらず、やっていることは、大したことありません!(笑)
Brainfuckの基本を学ぼう
連載第1回目では、まずは Brainfuck の仕組みを理解していきましょう!
Brainfuck には、8つの命令が存在します。
Brainfuckの命令
+ | ポインタの指す値を1加算する |
- | ポインタの指す値を1減算する |
> | ポインタを1つ進める |
< | ポインタを1つ戻す |
[ | ループ始まり:ポインタの指す値が0ならば] を指すポインタの一つ先に移動 |
] | ループ終わり:[ を指すポインタに移動 |
. | ポインタの値をASCIIコードで変換して出力 |
, | 入力を受け取る |
以上の8つの命令で、Brainfuck は成り立っているのです。
これ以外は、全てコメントとみなされます。
さて、ここで「ポインタ」という概念が出てきました。
ポインタについて、簡単に説明します!
ポインタ (Pointer)
ポインタとは、その名の通り「指すもの」を表します。
何を指しているかというと、メモリ番地です。
プログラミングの世界では、変数や関数を読み取るとき、その内容をメモリに保存します。
例えば、4バイト分のメモリを使用する整数型のint であれば、次のように保持されます。
これら変数にアクセスするときは、メモリ番地をもとに参照しますよね?
そのメモリ番地を指すのが、ポインタです。
この場合、変数num のポインタは「4」であり、「メモリ番地 4 」ということになります。
そこに格納されている値が、「123 (=0x007b)」ということです (「0x」は16進数)。
つまり、変数にアクセスしたときは、「まずはポインタで、メモリのどこに格納されているかを探し、その値を読み取る」というプロセスが起こっているわけですね!
ちなみに Brainfuck では、ポインタの初期値は「0」で、値も全て「0」です。
Brainfuckを実際に書いてみよう
では次に、実際に書きながら理解しましょう。
インタプリタは、WEBrainfuck のようなブラウザで動作するタイプでもいいですし、インタプリタをお手持ちの PC にインストールするタイプでも構いません。
macOS であれば、
1$ brew install brainfuck
で、できます。
Windows であれば、以下のリンクから、実行するでもいいでしょう。
【BFI.exe】
http://esoteric.sange.fi/brainfuck/compiled/win/BFI.exe
とりあえず 「H」 を出力させる
「Hello, world!」の前に、まずは一文字目の「H」を出力させてみましょう!
「H」は、ASCII コードでは、10進数で「72」です。
したがって、以下のようにポインタの指す値を「+」で72回インクリメントして、「.」で出力させれば良いのです。
1++++++++++++++++++++
2++++++++++++++++++++
3++++++++++++++++++++
4++++++++++++.
これで「H」が出力されます。
...が、この調子で「Hello, world!」を出力させようとすると、まずそうな雰囲気が漂ってきますね(笑)
そこで、[ と ] の出番です。
ループで綺麗に書く
Brainfuck にも、Brainfuck らしい綺麗なコード、というものがあります。
[ は、最初に解説したように、今ポインタが指している値が「0」であれば、] の一つ後へ飛ぶ命令。
そして ] は、 [ に飛ぶ命令です。
これを使って、スマートに「H」を出力してみましょう。
1++++++++++ # ループカウンタ
2[->+++++++<] # 7x10 = 70回インクリメント
3>++. # +2 して出力
これでも「H」が出力されるはずです。
記法はこの限りではありませんが、[ と ] を使うだけで、Brainfuck らしいコードになります。
このとき、0番地目のメモリはループカウンタ、1番地目のメモリは「H」の ASCII コードを保持しています。
さらに細かく紐解くと、以下のような感じ。
1++++++++++ # ループカウンタ
2[
3 -> # ループカウンタを一つ減らしてポインタを右シフト
4 +++++++ # +10
5 < # ポインタをループカウンタへ移動
6]
7>++. # +2 して出力
ここまでくれば、あなたはもう Brainfucker ですね!
Hello, world!
それでは「Hello, world!」に挑戦しましょう。
各 ASCII コードは以下になります。
H | 72 |
e | 101 |
l | 108 |
o | 111 |
, | 44 |
[スペース] | 32 |
w | 119 |
r | 114 |
d | 100 |
! | 33 |
メモリの使い方によって、実装方法はたくさんありますので、ここでは一例を示します。
1++++++++++[->+++++++<]>++. # 10 × 7 + 2 = 72
2>++++++++++[->++++++++++<]>+. # 10 × 10 + 1 = 101
3<+++[->++<]>+. # 101 + 3 × 2 + 1 = 108
4. # 108
5+++. # 108 + 3 = 111
6<<<++++[->-------<]>. # 72 ー 4 × 7 = 44
7<+++[->----<]>. # 44 ー 2 × 4 = 32
8>++[->++++<]>. # 111 + 2 × 4 = 119
9<++[->----<]>. # 111 ー 2 × 4 = 111
10+++. # 111 + 3 = 114
11<++[->---<]>. # 114 ー 2 × 3 = 108
12<++[->----<]>. # 108 ー 2 × 4 = 100
13<<+. # 32 + 1 = 33
冒頭の例とは違った例で、できるだけループを使うようにしてみました。
ちなみに、コメントの+ーは、わざと全角にしています。
1行につき一文字です。
これを改行なしで書くと、さらに Brainfuck 感が出ますね(笑)
1++++++++++[->+++++++<]>++.>++++++++++[->++++++++++<]>+.<+++[->++<]>+..+++.<<<++++[->-------<]>.<+++[->----<]>.>++[->++++<]>.<++[->----<]>.+++.<++[->---<]>.<++[->----<]>.<<+.
次回からはBrainfuckのインタプリタを作る
さて、Brainfuck の仕組みがわかったところで、いよいよ Brainfuck をデコードするインタプリタを作ってみましょう!
ポインタを扱うには、C/C++ が最適ですので、C/C++ の知識も同時に身につけていきます。
今回は、実装する前の予備知識として、Brainfuck を解説しました。
次回からは、いよいよ C/C++ を使って、インタプリタの実装をしていきます。
本連載では、今まで C/C++ を触ったことがないような人にも、理解できるような内容になっているので安心してくださいね!
それでは、次回をお楽しみに!
第2回はこちら!
こちらの記事もオススメ!
2020.07.17ライトコード的「やってみた!」シリーズ「やってみた!」を集めました!(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました!※作成日が新し...
2020.07.27IT・コンピューターの歴史特集IT・コンピューターの歴史をまとめていきたいと思います!弊社ブログにある記事のみで構成しているため、まだ「未完成状態」...
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ
「好きを仕事にするエンジニア集団」の(株)ライトコードです! ライトコードは、福岡、東京、大阪、名古屋の4拠点で事業展開するIT企業です。 現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。 いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。 システム開発依頼・お見積もり大歓迎! また、現在「WEBエンジニア」「モバイルエンジニア」「営業」「WEBデザイナー」を積極採用中です! インターンや新卒採用も行っております。 以下よりご応募をお待ちしております! https://rightcode.co.jp/recruit