Brainfuck Hello World实际如何运作? [英] How does the Brainfuck Hello World actually work?

查看:112
本文介绍了Brainfuck Hello World实际如何运作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人将此邮件发送给我,并声称这是Brainfuck的世界(我希望如此...)

Someone sent this to me and claimed it is a hello world in Brainfuck (and I hope so...)

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

我知道它可以通过移动指针,递增和递减的东西来工作的基础知识...

I know the basics that it works by moving a pointer and increment and decrementing stuff...

但是我仍然想知道,它实际上是如何工作的?首先如何在屏幕上打印任何内容?它如何编码文本?我根本听不懂...

Yet I still want to know, how does it actually work? How does it print anything on the screen in the first place? How does it encode the text? I do not understand at all...

推荐答案

1.基础

要了解Brainfuck,您必须想象无限个由0初始化的单元格的数组.

1. Basics

To understand Brainfuck you must imagine infinite array of cells initialized by 0 each.

...[0][0][0][0][0]...

当Brainfuck程序启动时,它指向任何单元格.

When brainfuck program starts, it points to any cell.

...[0][0][*0*][0][0]...

如果将指针右移>,则将指针从单元格X移动到单元格X + 1

If you move pointer right > you are moving pointer from cell X to cell X+1

...[0][0][0][*0*][0]...

如果增加单元格值+,则会得到:

If you increase cell value + you get:

...[0][0][0][*1*][0]...

如果再次增加单元格值+,则会得到:

If you increase cell value again + you get:

...[0][0][0][*2*][0]...

如果减小单元格值-,则会得到:

If you decrease cell value - you get:

...[0][0][0][*1*][0]...

如果将指针向左移动<,则将指针从单元格X移动到单元格X-1

If you move pointer left < you are moving pointer from cell X to cell X-1

...[0][0][*0*][1][0]...

2.输入

要读取字符,请使用逗号,.它的作用是:从标准输入中读取字符,并将其十进制ASCII码写入实际单元格.

2. Input

To read character you use comma ,. What it does is: Read character from standard input and write its decimal ASCII code to the actual cell.

看看 ASCII表.例如,!的十进制代码是33,而a的十进制代码是97.

Take a look at ASCII table. For example, decimal code of ! is 33, while a is 97.

好吧,让我们想象一下您的BF程序内存如下:

Well, lets imagine your BF program memory looks like:

...[0][0][*0*][0][0]...

假设标准输入代表a,如果使用逗号,运算符,则BF会执行以下操作:a十进制ASCII码97读入内存:

Assuming standard input stands for a, if you use comma , operator, what BF does is read a decimal ASCII code 97 to memory:

...[0][0][*97*][0][0]...

您通常想以这种方式思考,但是事实要复杂一些.事实是BF不会读取字符,而是读取一个字节(无论该字节是什么).让我给你举个例子:

You generally want to think that way, however the truth is a bit more complex. The truth is BF does not read a character but a byte (whatever that byte is). Let me show you example:

在Linux中

$ printf ł

打印:

ł

是特定的波兰字符.此字符未通过ASCII编码进行编码.在这种情况下,它是UTF-8编码,因此它过去在计算机内存中占用一个以上的字节.我们可以通过进行十六进制转储来证明这一点:

which is specific polish character. This character is not encoded by ASCII encoding. In this case it's UTF-8 encoding, so it used to take more than one byte in computer memory. We can prove it by making a hexadecimal dump:

$ printf ł | hd

其中显示:

00000000  c5 82                                             |..|

零偏移. 82是第一个字节,c5是第二个字节,代表ł(我们将按顺序读取它们). |..|是图形表示,在这种情况下是不可能的.

Zeroes are offset. 82 is first and c5 is second byte representing ł (in order we will read them). |..| is graphical representation which is not possible in this case.

好吧,如果将ł作为输入传递给读取单字节的BF程序,则程序存储器将如下所示:

Well, if you pass ł as input to your BF program that reads single byte, program memory will look like:

...[0][0][*197*][0][0]...

为什么197? 197十进制是c5十六进制.看起来很熟悉?当然.它是ł的第一个字节!

Why 197 ? Well 197 decimal is c5 hexadecimal. Seems familiar ? Of course. It's first byte of ł !

要使用点.打印字符,它的作用是:假设我们将实际单元格值视为十进制ASCII码,则将相应字符打印到标准输出.

To print character you use dot . What it does is: Assuming we treat actual cell value like decimal ASCII code, print corresponding character to standard output.

好吧,让我们想象一下您的BF程序内存如下:

Well, lets imagine your BF program memory looks like:

...[0][0][*97*][0][0]...

如果现在使用点(.)运算符,则BF会执行以下打印:

If you use dot (.) operator now, what BF does is print:

a

因为ASCII中的a十进制代码为97.

Because a decimal code in ASCII is 97.

例如,这样的BF程序(97加2点):

So for example BF program like this (97 pluses 2 dots):

++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++ ..

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++..

将其指向的单元格的值增加到最多97,然后将其打印2次.

Will increase value of the cell it points to up to 97 and print it out 2 times.

aa

4.循环

在BF循环中,循环由循环开始[和循环结束]组成.您可以认为这就像在C/C ++中,条件是实际单元格值.

4. Loops

In BF loop consists of loop begin [ and loop end ]. You can think it's like while in C/C++ where the condition is actual cell value.

在下面看看BF程序:

++[]

++将实际单元格值增加两次:

++ increments actual cell value twice:

...[0][0][*2*][0][0]...

[]就像while(2) {},所以它是无限循环.

And [] is like while(2) {}, so it's infinite loop.

让我们说我们不希望这个循环是无限的.我们可以例如:

Let's say we don't want this loop to be infinite. We can do for example:

++[-]

因此,每次循环循环都会减少实际单元格值.一旦实际单元格值为0,循环结束:

So each time a loop loops it decrements actual cell value. Once actual cell value is 0 loop ends:

...[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)

让我们考虑另一个有限循环的例子:

Let's consider yet another example of finite loop:

++[>]

此示例显示,我们尚未在循环开始于的单元格处完成循环:

This example shows, we haven't to finish loop at cell that loop started on:

...[0][0][*2*][0][0]...        loop starts
...[0][0][2][*0*][0]...        after first iteration (loop ends)

不过,好的做法是在我们开始的地方结束.为什么 ?因为如果循环结束了它开始的另一个单元格,则我们无法假定单元格指针将位于何处.老实说,这种做法可以减少脑筋.

However it is good practice to end where we started. Why ? Because if loop ends another cell it started, we can't assume where the cell pointer will be. To be honest, this practice makes brainfuck less brainfuck.

这篇关于Brainfuck Hello World实际如何运作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆