Кто-то отправил мне это и заявил, что это привет, мир в Brainfuck (и я надеюсь на это ...)
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
Я знаю основы, что он работает, перемещая указатель и увеличивая и уменьшая вещи ...
И все же я все еще хочу знать, как это на самом деле работает? Как он вообще что-нибудь печатает на экране? Как он кодирует текст? Я вообще не понимаю ...
brainfuck
esoteric-languages
повышающее устройство
источник
источник
Ответы:
1. Основы
Чтобы понять Brainfuck, вы должны представить себе бесконечный массив ячеек,
0
каждая из которых инициализируется .Когда программа brainfuck запускается, она указывает на любую ячейку.
Если вы перемещаете указатель вправо,
>
вы перемещаете указатель из ячейки X в ячейку X + 1.Если вы увеличите значение ячейки,
+
вы получите:Если вы снова увеличите значение ячейки,
+
вы получите:Если вы уменьшите значение ячейки,
-
вы получите:Если вы перемещаете указатель влево,
<
вы перемещаете указатель из ячейки X в ячейку X-1.2. Ввод
Чтобы прочитать символ, вы используете запятую
,
. Что он делает: читает символ из стандартного ввода и записывает его десятичный код ASCII в фактическую ячейку.Взгляните на таблицу ASCII . Например, десятичный код
!
равен33
, аa
есть97
.Что ж, давайте представим, что память вашей программы BF выглядит так:
Предполагая, что стандартный ввод означает
a
, если вы используете,
оператор запятой , BF считываетa
десятичный код ASCII97
в память:Обычно вы хотите так думать, однако истина немного сложнее. На самом деле BF читает не символ, а байт (каким бы он ни был). Позвольте мне показать вам пример:
В linux
печатает:
что является специфическим полировальным характером. Этот символ не кодируется кодировкой ASCII. В данном случае это кодировка UTF-8, поэтому раньше она занимала более одного байта в памяти компьютера. Мы можем доказать это, сделав шестнадцатеричный дамп:
который показывает:
Нули смещены.
82
является первым иc5
вторым байтами, представляющимиł
(чтобы мы их прочитали).|..|
это графическое представление, которое в данном случае невозможно.Что ж, если вы передадите в
ł
качестве ввода свою программу BF, которая читает один байт, программная память будет выглядеть так:Почему
197
? Ну,197
десятичная дробь -c5
шестнадцатеричная. Знакомо? Конечно. Это первый байтł
!3. Вывод
Для печати символа используется точка.
.
Что он делает: если мы обрабатываем фактическое значение ячейки как десятичный код ASCII, выводим соответствующий символ в стандартный вывод.Что ж, давайте представим, что память вашей программы BF выглядит так:
Если вы сейчас используете оператор точки (.), BF печатает:
Поскольку
a
десятичный код в ASCII есть97
.Так, например, программа BF (97 плюс 2 точки):
Увеличит значение указанной ячейки до 97 и распечатает его в 2 раза.
4. Петли
В BF цикл состоит из начала
[
и конца цикла]
. Вы можете думать, что это как в C / C ++, где условием является фактическое значение ячейки.Взгляните на программу BF ниже:
++
увеличивает фактическое значение ячейки в два раза:И
[]
вродеwhile(2) {}
, так это бесконечный цикл.Допустим, мы не хотим, чтобы этот цикл был бесконечным. Мы можем сделать, например:
Таким образом, каждый раз, когда цикл повторяется, фактическое значение ячейки уменьшается. Как только фактическое значение ячейки будет
0
завершено, цикл завершится:Рассмотрим еще один пример конечного цикла:
Этот пример показывает, что нам не нужно заканчивать цикл в ячейке, в которой цикл начался:
Однако рекомендуется заканчивать с того места, где мы начали. Зачем ? Поскольку, если цикл завершает другую ячейку, которую он начал, мы не можем предположить, где будет указатель ячейки. Если честно, такая практика делает мозги меньшими.
источник
В Википедии есть закомментированная версия кода.
Для того, чтобы ответить на ваши вопросы, то
,
и.
символы используются для ввода / вывода. Текст в формате ASCII.Википедии Статья продолжается более некоторой глубине, а также.
источник
,
и.
используется для ввода-вывода, так же, как C печатает с использованиемputchar
. Это деталь реализации, обрабатываемая компилятором.Чтобы ответить на вопрос, как он знает, что печатать, я добавил расчет значений ASCII справа от кода, в котором происходит печать:
источник
Brainfuck такое же, как и его название. В нем используется всего 8 символов,
> [ . ] , - +
что делает его самым быстрым языком программирования для изучения, но самым сложным для реализации и понимания. … .И заставляет вас, наконец, кончить тем, что вы трахаете свой мозг.Значения хранятся в массиве: [72] [101] [108] [111]
let, изначально указатель, указывающий на ячейку 1 массива:
>
переместить указатель вправо на 1<
переместить указатель влево на 1+
увеличить значение ячейки на 1-
увеличить значение элемента на 1.
распечатать значение текущей ячейки.,
вводить данные в текущую ячейку.[ ]
цикл, +++ [-] счетчик из 3 отсчетов bcz перед ним стоит 3 ′ + 'и - уменьшает переменную счетчика на 1 значение.значения, хранящиеся в ячейках, являются значениями ascii:
поэтому, ссылаясь на массив выше: [72] [101] [108] [108] [111], если вы сопоставите значения ascii, вы обнаружите, что это Hello Writtern
Congrats! вы узнали синтаксис BF
——- Что-то еще ———
давайте сделаем нашу первую программу, т.е. Hello World , после чего вы сможете написать свое имя на этом языке.
разбивая на части:
Создает массив из 4 ячеек (число>) и устанавливает счетчик 10 примерно так: —-psuedo code—-
поскольку значение счетчика хранится в ячейке 0, а> перемещается в ячейку 1, обновляет свое значение на + 7> перемещается в ячейку 2, увеличивает на 10 до предыдущего значения и так далее….
<<<
вернуться в ячейку 0 и уменьшить ее значение на 1следовательно, после завершения цикла у нас есть массив: [70,100,30,10]
перемещается к 1-му элементу и увеличивает его значение на 2 (два '+'), а затем печатает символ ('.') с этим значением ascii. например, в python: chr (70 + 2) # печатает 'H'
переходит на 2-ю ячейку с приращением 1 к ее значению 100 + 1 и печатает ('.') ее значение, т.е. chr (101) chr (101) # печатает 'e', теперь в следующем фрагменте нет> или <, поэтому он принимает текущее значение последнего элемента и только приращение к нему
последний элемент = 101, следовательно, 101 + 7 и печатает его дважды (так как есть два '..') chr (108) #prints l дважды можно использовать как
——— Где это используется? ---
Это просто язык шуток, созданный для вызова программистов, который практически нигде не используется.
источник
Все ответы обстоятельны, но в них отсутствует одна крошечная деталь: печать. Создавая свой переводчик для мозгов, вы также учитываете характер
.
, это на самом деле то, как выглядит печатное выражение в мозговом обтекании. Итак, что должен делать ваш мозговой переводчик, так это то, что всякий раз, когда он встречает.
символ, он печатает текущий указанный байт.Пример:
предположим, что у вас есть ->
char *ptr = [0] [0] [0] [97] [0]
... если это утверждение для мозгов:>>>.
ваш указатель должен быть перемещен на 3 пробела вправо в:,[97]
так что теперь*ptr = 97
, после этого ваш переводчик встречает a.
, он должен затем вызватьили любой эквивалентный оператор печати для печати текущего указанного байта, который имеет значение 97, и буква
a
будет затем напечатана наstd_output
.источник
Я думаю, вы спрашиваете, как Brainfuck знает, что делать со всем кодом. Существует синтаксический анализатор, написанный на языке более высокого уровня, например Python, для интерпретации значения точки или знака добавления в коде.
Таким образом, синтаксический анализатор будет читать ваш код построчно и сообщать, что есть символ>, поэтому мне нужно продвинуть ячейку памяти, код просто, if (содержимое в этой ячейке памяти) ==>, memlocation = + memlocation, которое является написано на языке более высокого уровня, аналогично if (содержимое в ячейке памяти) == ".", затем print (содержимое ячейки памяти).
Надеюсь, это проясняет ситуацию. дц
источник