Brainfuck, вероятно, это самый безумный язык
программирования, который встречается на
свете. Сам язык состоит всего из 8
операторов, которыми можно написать
практически любую программу, которую вы
хотите. Для работы вам понадобится:
компилятор или интерпретатор (приводятся в
конце статьи — компилятор на ассемблере,
интерпретатор Brainfuck-C); ASCII таблица; вероятно
калькулятор :).

Основы

Главная идея Brainfuck — манипулирование
памятью. Вам выдается 30.000 массив 1 байтовых
блоков, хотя на самом деле размер массива
зависит от компилятора или интерпретатора,
но стандартный размер — 30.000. Внутри этого
массива вы можете увеличивать указатель,
значение в ячейке и так далее. Для работы,
как я уже говорил, используется 8
операторов:

> = увеличение указателя памяти или
смещение право на 1 блок
< = уменьшение или смещение влево на 1 блок
+ = увеличение значения в ячейке памяти, на
которую ссылается указатель
— = соответственно уменьшение на единиц
[ = аналог цикла while(cur_block_value != 0)
] = если значение в ячейке на которую
указывает указатель не равно нулю, то
переход на [
, = аналог getchar(), ввод одного символа
. = аналог putchar(), вывод одного сивола на
кончоль

Вводные правил

  • Любые символы кроме описанных выше
    игнорируются
  • Все значения в памяти устанавливаются
    на 0 в начале работы программы
  • Циклов может быть сколько угодно, однако
    каждая [ должна заканчиваться]

И вернемся к нашим баранам. Напишем
простую программу:

[-]

Что делается? По идее открывается цикл,
уменьшается значение текущей ячейки на 1 и
цикл продолжается до тех пор, пока значение
не достигнет 0. Однако так как изначально
все значения в памяти и есть 0, цикл никогда
не начнется. 

Напишем другую программу:

+++++[-]

На С это аналогично такой программе:

*p=+5;
while(*p != 0){
*p—;
}

В этой программе мы увеличили значение по
указателю на 5, потом открыли цикл, который
уменьшал значение до 0. 

>>>>++

На выходе мы получим такой вид памяти.

Очевидно, что сначала мы увеличиваем
указатель на 4 и затем два раза увеличиваем
значение на 1 два раза. Разнообразим?

>>>>++<<+>>+

Получаем:

Опять же понятно, что сначала 2
записывается в четвертую ячейку, потом 1 во
вторую и затем еще раз 1 прибавляется к 4. 

Давайте напишем программу, которая будет
уже выводить нечто в консоль, например
любимый всеми нами «Hello world». Выглядит
она так:

>+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.
+++++++..+++.[-]>++++++++[<++++>-] <.
>+++++++++++[<++++++++>-]<-.--------.+++
.——.———.[-]>++++++++[<++++>— ]<+.[-]++++++++++.

Круто? Настоящий Brainfuck… Разберем что
происходит. Надо помнить, что мы имеем дело
с кодами ASCII для вывода, так что надо
оперировать именно такими кодами.

Первая часть:

>+++++++++[<++++++++>-]<.

Сдвигаемся вправо, оставляя первую ячейку
пустой, записываем туда 9, открываем цикл. В
цикле смещаемся влево, записываем туда 8,
смещаемся вправо и уменьшаем значение на единицу.

Цикл идет до тех пор, пока во второй ячейке
не станет 0. Не слишком трудные вычисления
покажут, что в конце работы программы в
первой ячейки памяти будет 72, во второй 0.
Это код буквы Н, поэтому выводим ее в
консоль. Продолжаем для каждого символа и в
конце концов получаем заветные Hello world!
Занятно, не правда ли? 🙂

(Продолжение следует)

Оставить мнение

Check Also

Цифровой паноптикум. Настоящее и будущее тотальной слежки за пользователями

Даже если ты тщательно заботишься о защите своих данных, это не даст тебе желаемой приватн…