1. The basics
To understand Brainfuck, you have to represent an infinite array of cells initialized with each 0 .
...[0][0][0][0][0]...
When the brainfuck program starts, it points to any cell.
...[0][0][*0*][0][0]...
If you move the pointer to the right > , you move the pointer from cell X to cell X + 1
...[0][0][0][*0*][0]...
If you increase the value of cell + , you get:
...[0][0][0][*1*][0]...
If you increase the value of cell + again, you get:
...[0][0][0][*2*][0]...
If you decrease the value of cell - , you will get:
...[0][0][0][*1*][0]...
If you move the pointer to the left < , you move the pointer from cell X to cell X-1
...[0][0][*0*][1][0]...
2. Enter
To read a character, you use a comma,. What it does: read the character from standard input and write its decimal ASCII code into the actual cell.
See the ASCII table . For example, a decimal code ! is 33 , and a is 97 .
Well, imagine that your BF program memory looks like this:
...[0][0][*0*][0][0]...
Assuming standard input means a , if you use the comma operator, then what BF does is read a decimal ASCII code 97 into memory:
...[0][0][*97*][0][0]...
Usually you think so, but the truth is a little more complicated. The truth is that the BF does not read a character, but a byte (no matter what this byte is). Let me show you an example:
In linux
$ printf Ε
prints:
Ε
which is specific Polish character. This character is not ASCII encoded. In this case, this is UTF-8 encoding, so it used more than one byte in the computer's memory. We can prove this by making a hex dump:
$ printf Ε | hd
which shows:
00000000 c5 82 |..|
Zeros are offset. 82 is the first, and c5 is the second byte representing Ε (so that we read them). |..| - This is a graphical representation that is not possible in this case.
Well, if you pass Ε as input to your BF program, which reads one byte, the program memory will look like this:
...[0][0][*197*][0][0]...
Why 197 ? Well 197 decimal symbol c5 hexadecimal. Seems familiar? Sure. This is the first byte Ε !
3. Exit
To print the character you use dot . What it does: Assuming we treat the actual value of the cell as an ASCII decimal code, print the corresponding character to standard pins.
Well, imagine that your BF program memory looks like this:
...[0][0][*97*][0][0]...
If you are now using the dot (.) Operator, then what BF does is print:
but
Since a decimal code in ASCII is 97 .
So, for example, a BF program like this (97 pluses 2 points):
++++++++++++++++++++++++++++++++++++++++++++++++++ +++ ++++++++++++++++++++++++++++++++++++++++++++++++++ ..
Increases the value of the cell to which it points to 97, and prints it 2 times.
aa
4. Loops
In a loop, BF consists of a begin loop [ and the end of a loop ] . You can think of it like in C / C ++, where the condition is the actual value of the cell.
Check out the BF program below:
++[]
++ increments the value of the actual cell twice:
...[0][0][*2*][0][0]...
And [] is similar to while(2) {} , so this is an infinite loop.
Say we do not want this cycle to be infinite. We can do, for example:
++[-]
Thus, each time a loop cycle decreases the actual value of the cell. When the actual value of cell 0 ends with the end:
...[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)
Consider another example of a finite loop:
++[>]
This example shows that we should not end the cycle in the cell where the cycle was started:
...[0][0][*2*][0][0]... loop starts ...[0][0][2][*0*][0]... after first iteration (loop ends)
However, this is a great practice with which we started. What for? Since if the loop terminates another cell, we cannot assume where the cell pointer will be. Honestly, this practice makes brain injection less brain.