有人给我发了这个,声称这是Brainfuck中的hello world(我希望如此…)
++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
我知道它的基本原理是通过移动指针和递增或递减来工作。。。
但我还是想知道,它到底是如何工作的?它首先是如何在屏幕上打印任何东西的?它是如何编码文本的?我完全不明白。。。
Brainfuck和它的名字一样。它只使用8个字符
它以数组形式存储值:[72][101][108][111]
let,最初指向数组单元格1的指针:
>
<代码>
将单元格的值增加1
-
将元素的值增加1
打印当前单元格的值。
,
将输入输入到当前单元格。
[]
循环,[-]计数器的3个计数bcz它前面有3′,并且-将计数变量递减1个值。
存储在单元格中的值是ascii值:
参考上面的数组:[72][101][108][108][111],如果你匹配ascii值,你会发现它是Hello Writern
恭喜!你已经学会了BF的语法
---更多的东西---
让我们制作我们的第一个程序,即Hello World,之后你可以用这种语言写下你的名字。
+++++ +++++[> +++++ ++ >+++++ +++++ >+++ >+ <<<-]>++.>+.+++++ ++..+++.++.+++++ +++++ +++++.>.+++.----- -.----- ---.>+.>.
碎裂:
+++++ +++++[> +++++ ++
>+++++ +++++
>+++
>+
<<<-]
创建一个4个单元格的数组
array =[7,10,3,1]
i=10
while i>0:
element +=element
i-=1
因为计数器值存储在单元格0和
<代码>
因此,在循环完成后,我们有了数组:[70100,30,10]
>++.
移动到第1个元素并将其值增加2(两个“”),然后用该ascii值打印(“.”)字符。i、 例如python中的e:chr(702)#打印'H'
>+.
移动到第二个单元格增量1,使其值为100 1,并打印('.')其值,即chr(101)chr(101)#打印'e'现在没有
+++++ ++..
因此,最新元素=101,101 7并打印两次(因为有两个“…”)chr(108)#打印l两次可以用作
for i in array:
for j in range(i.count(‘.’)):
print_value
---在哪里使用---
它只是一种用来挑战程序员的玩笑语言,实际上并不在任何地方使用。
维基百科有一个注释版本的代码。
+++++ +++++ initialize counter (cell #0) to 10
[ use loop to set the next four cells to 70/100/30/10
> +++++ ++ add 7 to cell #1
> +++++ +++++ add 10 to cell #2
> +++ add 3 to cell #3
> + add 1 to cell #4
<<<< - decrement counter (cell #0)
]
> ++ . print 'H'
> + . print 'e'
+++++ ++ . print 'l'
. print 'l'
+++ . print 'o'
> ++ . print ' '
<< +++++ +++++ +++++ . print 'W'
> . print 'o'
+++ . print 'r'
----- - . print 'l'
----- --- . print 'd'
> + . print '!'
> . print '\n'
要回答您的问题,、
和。
字符用于I/O。文本是ASCII。
维基百科的文章也进行了更深入的讨论。
第一行通过简单地从0递增十倍来初始化a[0]=10
。第2行的循环有效地设置了数组的初始值:a[1]=70
(接近72,字符“H”的ASCII代码)、a[2]=100
(接近101或“e”)、a[3]=30
(接近32,空格代码)和a[4]=10
(换行)。循环的工作原理是每次通过循环分别向a[1]
、a[2]
、a[3]
和a[4]
单元格添加7、10、3和1,每个单元格总共添加10次(给出a[1]=70
等)。循环完成后,a[0]
为零<代码>
下一行将数组指针移动到a[2]
并向其中添加一个指针,生成101,即小写字母“e”,然后输出。
由于'l'恰好是'e'之后的第七个字母,为了输出'll',在a[2]
中添加另外七个(),结果输出两次。
“o”是“l”之后的第三个字母,因此a[2]
再递增三次并输出结果。
程序的其余部分以同样的方式进行。对于空格和大写字母,选择不同的阵列单元,并根据需要递增或递减。
要理解Brainfuck,您必须想象无限的单元格数组,每个单元格由0
初始化。
...[0][0][0][0][0]...
当brainfuck程序启动时,它指向任何细胞。
...[0][0][*0*][0][0]...
如果你向右移动指针
...[0][0][0][*0*][0]...
如果增加单元格值,则会得到:
...[0][0][0][*1*][0]...
如果再次增加单元格值,则会得到:
...[0][0][0][*2*][0]...
如果减少单元格值
-
,则会得到:
...[0][0][0][*1*][0]...
如果向左移动指针
...[0][0][*0*][1][0]...
要读取字符,您可以使用逗号
,
。它的作用是:从标准输入中读取字符,并将其十进制ASCII代码写入实际单元格。
看看ASCII表。例如,
的十进制代码
是
33
,而a
是97
。
让我们想象一下你的BF程序内存是这样的:
...[0][0][*0*][0][0]...
假设标准输入代表
a
,如果使用逗号,
运算符,BF所做的是将a
十进制ASCII码97
读取到内存:
...[0][0][*97*][0][0]...
你通常想这样想,然而事实有点复杂。事实是BF不读取字符,而是读取字节(不管字节是什么)。让我给你举个例子:
在linux
$ printf ł
印刷品:
ł
这是特定的波兰字符。这个字符不是用ASCII编码的。在这种情况下,它是UTF-8编码,所以它过去在计算机内存中需要一个以上的字节。我们可以通过十六进制转储来证明这一点:
$ printf ł | hd
这表明:
00000000 c5 82 |..|
零是偏移量
82
是第一个字节,c5
是第二个字节,代表ł
(我们将按顺序读取它们)<代码>||
是图形表示,在这种情况下不可能。
好吧,如果你把
ł
作为输入传递给你的BF程序,该程序读取单个字节,程序内存将如下所示:
...[0][0][*197*][0][0]...
为什么
十进制是197
?嗯,197c5
十六进制。看起来很熟悉吗?当然。这是的第一个字节!
要打印字符,请使用点
它的作用是:假设我们像对待十进制ASCII码一样对待实际单元格值,将相应的字符打印到标准输出。
让我们想象一下你的BF程序内存是这样的:
...[0][0][*97*][0][0]...
如果使用点(.)接线员现在BF要做的是打印:
A.
因为ASCII中的
a
十进制代码是97
。
比如像这样的BF程序(97加2点):
..
将其指向的单元格的值增加到97,并打印两次。
AA级
在BF中,循环由循环开始
[
和循环结束]
组成。你可以认为这就像在C/C中,条件是实际的单元值。
看看下面的BF程序:
++[]
将实际单元格值增加两次:
...[0][0][*2*][0][0]...
和
[]
类似于而(2){}
,所以它是无限循环。
假设我们不希望这个循环是无限的。例如,我们可以做:
++[-]
所以每次循环都会减少实际的单元值。一旦实际单元格值为
0
循环结束:
...[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)
让我们考虑另一个有限循环的例子:
++[>]
这个例子显示,我们还没有在循环开始的单元格中完成循环:
...[0][0][*2*][0][0]... loop starts
...[0][0][2][*0*][0]... after first iteration (loop ends)
然而,从我们开始的地方结束是一种很好的做法。为什么?因为如果循环结束了它开始的另一个单元格,我们不能假设单元格指针将在哪里。老实说,这种做法让脑力操变得不那么脑力操。
以下代码片段来自维基百科,是标准Hello World的序言!Brainfuck中的程序。。。 我理解这里发生的事情的要点,但是我不明白的是第3行到第6行发生的事情的机制。如果给中的值增加10,为什么将指针增加1并执行7次会导致等于70?难道不应该吗?看起来通过神奇地增加了10倍,我不明白为什么。
4.2. Hello,世界 让我们从经典的"Hello, World"程序开始: 05 package main 07 import fmt "fmt" // Package implementing formatted I/O. 09 func main() { 10 fmt.Printf("Hello, world; or Καλημ?ρα
> < li> 如何生成“304未修改”响应? 浏览器如何确定对HTTP请求的响应是否为304? 是浏览器设置的还是服务器发来的 如果由服务器发送,服务器如何知道缓存中可用的数据,以及如何将304设置为图像? 我猜,如果它是由浏览器生成的: 我依靠第三方API提供商来获取数据,解析 我想使用相同类型的算法来确定数据的变化。
我们为项目创建了一个package.json文件。 现在我们将使用Electron创建我们的第一个桌面应用程序。 创建一个名为main.js的新文件。 在其中输入以下代码 - const {app, BrowserWindow} = require('electron') const url = require('url') const path = require('path') let
为了测试你的安装,我们创建一个简单的应用程序hello world.打开Qt Creator并且创建一个Qt Quick UI Project(File->New File 或者 Project-> Qt Quick Project -> Qt Quick UI)并且给项目取名 HelloWorld。 注意 Qt Creator集成开发环境允许你创建不同类型的应用程序。如果没有另外说明,我们都创建
在这个例子中,我们将创建一个基于Spring Boot + MVC + Rest的Web应用程序。 第1步:创建源文件夹 在E:\Test folder.创建文件夹FirstApplication E:\Test folder. 第2步:创建源文件 使用以下源代码在E:\Test folder创建FirstApplication.groovy文件 - @RestController class F