Brainfuck 编程语言

很偶然的机会认识到这个语言,当时在纸上对着它的 "hello world" 程序一个字符一个字符的解释了一遍,惊讶于它的设计思想。到网上查了下,记录下来。

以下是正文 :

--------------------------------

Brainfuck,是一种极小化的计算机语言,它是由Urban Müller在1993年创建的。由于fuck在英语中是脏话,这种语言有时被称为brainf*ck或brainf***,甚至被简称为BF。

Müller的目标是创建一种简单的、可以用最小的编译器来实现的、符合图灵完全思想的编程语言。这种语言由八种运算符构成,为Amiga机器编写的编译器(第二版)只有240个字节大小。

就象它的名字所暗示的,brainfuck程序很难读懂。尽管如此,brainfuck图灵机一样可以完成任何计算任务。虽然brainfuck的计算方式如此与众不同,但它确实能够正确运行。

这种语言基于一个简单的机器模型,除了指令,这个机器还包括:一个以字节为单位、被初始化为零的数组、一个指向该数组的指针(初始时指向数组的第一个字节)、以及用于输入输出的两个字节流。

下面是这八种状态的描述,其中每个状态由一个字符标识: 
字符 含义 
>    指针加一 
<    指针减一 
+    指针指向的字节的值加一 
-     指针指向的字节的值减一 
.     输出指针指向的单元内容(ASCII码) 
,     输入内容到指针指向的单元(ASCII码) 
[     如果指针指向的单元值为零,向后跳转到对应的]指令的次一指令处 
]     如果指针指向的单元值不为零,向前跳转到对应的[指令的次一指令处

(按照更节省时间的简单说法,]也可以说成“向前跳转到对应的[状态”。这两解释是一样的。)

(第三种同价的说法,[意思是"向后跳转到对应的]",]意思是"向前跳转到对应的[指令的次一指令处,如果指针指向的字节非零。")

Brainfuck程序可以用下面的替换方法翻译成C语言(假设ptr是char*类型): 
Brainfuck C 
>    ++ptr; 
<    --ptr; 
+    ++*ptr; 
-     --*ptr; 
.     putchar(*ptr); 
,     *ptr =getchar(); 
[     while (*ptr) { 
]     }

(以上内容源自维基百科:http://zh.wikipedia.org/wiki/Brainfuck)

下面是它的一个解释器: 
--------------------------------

#include <stdio.h>
int p, r, q;
char a[5000], f[5000], b, o, *s=f;
void interpret(char *c)
{
    char *d;
    r++;
    while( *c ) {
        //if(strchr("<>;+-,.[]\n",*c))printf("%c",*c);
        switch(o=1,*c++) {
            case ‘<‘: p--; break;
            case ‘>‘: p++; break;
            case ‘+‘: a[p]++; break;
            case ‘-‘: a[p]--; break;
            case ‘.‘: putchar(a[p]); fflush(stdout); break;
            case ‘,‘: a[p]=getchar();fflush(stdout); break;
            case ‘[‘:
                for( b=1,d=c; b && *c; c++ )
                b+=*c==‘[‘, b-=*c==‘]‘;
                if(!b) {
                    c[-1]=0;
                    while( a[p] )
                    interpret(d);
                    c[-1]=‘]‘;
                    break;
                }
            case ‘]‘:
                puts("UNBALANCED BRACKETS"), exit(0);
            case ‘#‘:
                if(q>2)
                printf("%2d %2d %2d %2d %2d %2d %2d %2d %2d %2d\n%*s\n",
                *a,a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],3*p+2,"^");
                break;
            default: o=0;
        }
        if( p<0 || p>100)
            puts("RANGE ERROR"), exit(0);
    }
    r--;
    // chkabort();
}
 
main(int argc,char *argv[])
{
    FILE *z;
 
    q=argc;
 
    if(z=fopen(argv[1],"r")) {
        while( (b=getc(z))>0 )
            *s++=b;
        *s=0;
        interpret(f);
    }
}

-------------------------------- 
代码比较直接,不做解释了。

一个 BF 的 hello world ( 注意,这里成行的减号是起分割线作用的,不是 BF 代码。)
-------------------------------- 
++++++++++[>+++++++>++++++++++>+++>+<<<<-] 
>++.>+.+++++++..+++.>++.<<+++++++++++++++. 
>.+++.------.--------.>+.>. 
--------------------------------

解释 
-------------------------------- 
+++ +++ +++ +                    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‘ 
--------------------------------

(以上内容来自 coolshell : http://coolshell.cn/articles/1142.html,作者: 陈皓)

在网上又查到了一个代码写得很好的解释器,代码如下: 
--------------------------------

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define TOKENS "><+-.,[]"
#define CODE_SEGMENT_SIZE 30000
#define STACK_SEGMENT_SIZE 1000
#define DATA_SEGMENT_SIZE 30000
typedef void (*Callback)(void);
struct {
  char cs[CODE_SEGMENT_SIZE]; /* Code Segment */
  long ip; /* Instruction Pointer */
 
  char ss[STACK_SEGMENT_SIZE]; /* Stack Segment */
  long sp; /* Stack Pointer */
 
  char ds[DATA_SEGMENT_SIZE]; /* Data Segment */
  long bp; /* Base Pointer */
 
  Callback fn[128];
} vm;
void vm_forward() {
  vm.bp = (vm.bp + 1) % DATA_SEGMENT_SIZE;
}
void vm_backward() {
  vm.bp = (vm.bp + DATA_SEGMENT_SIZE - 1) % DATA_SEGMENT_SIZE;
}
void vm_increment() {
  vm.ds[vm.bp]++;
}
void vm_decrement() {
  vm.ds[vm.bp]--;
}
void vm_input() {
  vm.ds[vm.bp] = getchar();
}
 
void vm_output() {
  putchar(vm.ds[vm.bp]);
}
void vm_while_entry() {
  if (vm.ds[vm.bp]) {
    vm.ss[vm.sp] = vm.ip - 1;
    vm.sp++;
  } else {
    int c = 1;
    for (vm.ip++; vm.cs[vm.ip] && c; vm.ip++) {
      if (vm.cs[vm.ip] == ‘[‘) {
        c++;
      } else if (vm.cs[vm.ip] == ‘]‘) {
        c--;
      }
    }
  }
}
void vm_while_exit() {
  if (vm.ds[vm.bp]) {
    vm.sp--;
    vm.ip = vm.ss[vm.sp];
  }
}
void setup() {
  int c;
  int i;
 
  memset(&vm, 0, sizeof(vm));
  vm.fn[‘>‘] = vm_forward;
  vm.fn[‘<‘] = vm_backward;
  vm.fn[‘+‘] = vm_increment;
  vm.fn[‘-‘] = vm_decrement;
  vm.fn[‘.‘] = vm_output;
  vm.fn[‘,‘] = vm_input;
  vm.fn[‘[‘] = vm_while_entry;
  vm.fn[‘]‘] = vm_while_exit;
 
  for (i = 0; (c = getchar()) != EOF;) {
    if (strchr(TOKENS, c)) {
      vm.cs[i] = c;
      i++;
    }
  }
}
void run() {
  while (vm.cs[vm.ip]) {
    vm.fn[vm.cs[vm.ip]]();
    vm.ip++;
  }
}
 
int main(int argc, char* argv[]) {
  if (argc > 1) {
    freopen(argv[1], "r", stdin);
  }
 
  setup();
  run();
 
  return 0;
}

--------------------------------

(以上内容来自 http://blog.csdn.net/redraiment/article/details/7483062,作者:redraiment)

代码清晰易懂,不再解释了。

上面提到的图灵完备之类的概念是计算机科学(CS)中的内容,有兴趣的可以自行参考维基百科介绍,然后再决定是否要进一步的了解。不过,先提个醒,CS 是个很大很引人入胜的领域,小心“沉迷”。

时间: 2024-08-06 18:04:51

Brainfuck 编程语言的相关文章

CTF中那些脑洞大开的编码和加密

0x00 前言 正文开始之前先闲扯几句吧,玩CTF的小伙伴也许会遇到类似这样的问题:表哥,你知道这是什么加密吗?其实CTF中脑洞密码题(非现代加密方式)一般都是各种古典密码的变形,一般出题者会对密文进行一些处理,但是会给留一些线索,所以写此文的目的是想给小伙伴做题时给一些参考,当然常在CTF里出现的编码也可以了解一下.本来是想尽快写出参考的文章,无奈期间被各种事情耽搁导致文章断断续续写了2个月,文章肯定有许多没有提及到,欢迎小伙伴补充,总之,希望对小伙伴们有帮助吧! 0x01 目录 1 2 3

1987年国际C语言混乱代码大赛获奖的一行代码

macb() ? lpcbyu(&gbcq/_\021%ocq\012\0_=w(gbcq)/_dak._=}_ugb_[0q60)s+ 这是CoolShell博主之前做了一个很有意思的在线puzzle,仿照一些前端过关的游戏,做了几个和程序员有关的迷题,一个通关游戏,这个事测试的第二题.并为通关的前十名送上<Unix环境高级编程(第三版)>(感谢@出版圈郭志敏 赞助)或一个马克杯(感谢@linux命令行精选网 赞助))这些谜题很有趣同时也有一定的难度.由于水平有限,我并没有通关,但我

常见编程语言对REPL支持情况小结[转]

文章转载自http://www.nowamagic.net/librarys/veda/detail/2462 最近跟一个朋友聊起编程语言的一些特性,他有个言论让我略有所思:“不能REPL的都是渣”.当然这个观点有点偏激,但我们可以探究一下,我们常用的编程语言里面,哪些支持REPL,哪些不支持,还有REPL的一些概况. 在一般的脚本语言中,有REPL是常态,因为REPL非常的方便.编程术语 REPL(Read-Eval-Print Loop) 中文的话有翻译成“交互式解释器”或“交互式编程环境”

介绍两个比较好玩的编程语言

BF语言介绍 Brainfuck,是一种极小化的计算机语言,这种 语言,是一种按照"Turing complete(完整图灵机)"思想设计的语言,它的主要设计思路是:用最小的概念实现一种"简单"的语言,BrainFuck 语言只有八种符号,所有的操作都由这八种符号的组合来完成.BF基于一个简单的机器模型,除了八个指令,这个机器还包括:一个以字节为单位.被初始化为零的数组.一个指向该数组的指针(初始时指向数组的第一个字节).以及用于输入输出的两个字节流. 下面是这八种

所有计算机编程语言的一句话概括

A+:阵列编程语言,由摩根·斯坦利公司在1980年代在APL的基础上开发起来的,现在使用GPL授权. Ada:是一种表现能力很强的通用程序设计语言,它能大大改善软件系统的清晰性, 可靠性, 有效性, 可维护性. Assembly language(汇编语言):是用于电子计算机.微处理器.微控制器或其他可编程器件的低级语言,又为符号语言. B语言:是贝尔实验室开发的一种通用的程序设计语言. BF:Brainfuck(BF)是一种极小化的计算机语言,因为f*ck在英语中是脏话,这种语言有时被称为br

转:几十种编程语言的快速入门教程- learnxinyminutes.com

原文来自于:http://top.jobbole.com/15551/ 这家网站的名称是 Learn X in Y minutes,包括了几十种编程语言的快速学习入门教程.打开几种编程语言来看了一下,教程的形式大同小异.以代码加注释的方式,来具体介绍语言的特性. 其中含中文版的教程包括: brainfuck c c# clojure clojure macros coffeescript Common Lisp css dart elisp elixir erlang Go Haskell ja

常见编程语言对REPL支持情况小结

最近跟一个朋友聊起编程语言的一些特性,他有个言论让我略有所思:“不能REPL的都是渣”.当然这个观点有点偏激,但我们可以探究一下,我们常用的编程语言里面,哪些支持REPL,哪些不支持,还有REPL的一些概况. 在一般的脚本语言中,有REPL是常态,因为REPL非常的方便.编程术语 REPL(Read-Eval-Print Loop) 中文的话有翻译成“交互式解释器”或“交互式编程环境”的.不过我觉得不用翻译,直接REPL就好了,这样的术语,翻译成中文后,读者更难理解.下面是对 REPL 的解释:

转 13种最为荒谬的编程语言(Bugku 加密)

今天在做关于Bugku的加密题目时,出现了一些不会的题目,上网搜索一下发现自己不知道的真的比较多(QAQ)我就把今天遇到的问题写下来,以便自己的查找,更希望能够帮助到那些需要帮助的人!! 1.Lolcode LOLCODE是一种建立在高度缩写的网络英语之上的编程语言,一般来说如果一个人能理解这种网络英语就能在未经训练的情况下读懂LOLCODE程序源代码. 2.Befunge Befunge这门语言由Chris Pressey在1993年创造,本意为设计一种尽量难编译的语言--结果马上出现了一批编

编程语言评价标准

编程语言需要提供足够简单和丰富的概念来表达我们要描述的世界: 并且执行的效率要足够高 Enough of the small talk, how do we go about comparing these two goliaths? In reality this can’t be a true comparison, as Angular is a framework and React a library; but we will be looking at some of the imp