문서:BrainFuck

문서의 이전 버전(r44)을 보고 있습니다.

역사 raw
대문 랜덤 문서 최근 토론
1. 개요2. 명령어3. 메모리 구조4. 예제
4.1. [[Hello, world!]]
4.1.1. 해설
4.2. [[Hello, world!]] 노가다 출력
5. 기타


1. 개요

Brainfuck 뇌병신
대표적인 난해한 프로그래밍 언어. 1993년 우어반 뮐러가 제작했으며 제작된 파일 확장자는 .b/.bf.

개발 목적은 가장 작은 컴파일러로 구현할 수 있는 튜링 완전[1] 프로그래밍 언어를 만드는 것이었다고 한다. 세상에서 가장 단순하면서 복잡한 언어라는 말이 어울리는 언어로, 프로그래밍에 사용되는 문자는 +-][><,. 로 딱 8개다.

프로그래밍 방법은 엄청나게 난해하지만, 일단 튜링 완전 타입의 언어이기 때문에 이론적으로는 컴퓨터가 할 수 있는 모든 일을 다 할 수 있다. 그리고 컴퓨터의 연산이 작동하는 방법을 이해하고 있다면, "배우는" 것은 매우 쉽고 단순하다. 실제로 사용하기가 매우 난해한 게 문제다. 일단은 일반적인 난해한 프로그래밍 언어들이 다 그렇듯이 포인터를 기본으로 한 명령 체계를 사용하고 있으며 명령어들 역시 포인터를 옮기는 명령어들로 구성되어 있다.

참고로 이름인 브레인의 퍽은... 이 글을 보는 사람들이 생각하는 그 퍽이 맞다. Brainfuck이다. 말 그대로 보는 사람의 를 과부하로 조지려고 만든 변태 프로그래밍 언어다. 그래서 욕설 필터에 걸리는 경우가 있기 때문에 Brainf*** , 또는 약자만 따서 B.F. 등으로 부르는 경우가 많다고 한다.

2. 명령어

  • > : 포인터 증가
  • < : 포인터 감소
  • + : 포인터가 가리키는 바이트의 값을 증가
  • - : 포인터가 가리키는 바이트의 값을 감소
  • . : 포인터가 가리키는 바이트 값을 아스키 코드 문자로 출력한다.
  • , : 포인터가 가리키는 바이트에 아스키 코드 값을 입력한다. 쉽게 말해서 입력 받는 역할이다.
  • [ : 포인터가 가리키는 바이트의 값이 0이 되면 짝이 되는 ]로 이동한다. 의사코드로는 while(*ptr != 0) {...} 이다.
  • ] : 포인터가 가리키는 바이트의 값이 0이 아니면 짝이 되는 [로 이동한다.

이외에 공백, 엔터 등 기타 문자는 모두 처리되지 않는다.[2]

3. 메모리 구조

1바이트 정수(char)로 이루어진 32768개의 배열과 포인터 하나가 메모리의 전부.
따라서 총 메모리 공간은 32KB + 4B이다.
물론 인터프린터의 구현체별로 당연히 차이가 있다. 한 자바 구현체의 경우는 65535개의 포인터가 있는 대신 4바이트가 아닌 1바이트로 처리한다.

4. 예제

4.1. Hello, world!


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

4.1.1. 해설

이 문단에서는 위 프로그램이 어떻게 동작하여 Hello, World!를 출력하는지를 설명한다. 포인터는 처음에 0번 주소를 가리키고 있으며, 모든 메모리의 초기값은 0임을 잊지 말자. 가독성을 위하여 필요한 부분에는 띄어쓰기를 하였다.
그 전에 잠깐 포인터에 대한 설명을 하자면, 포인터는 메모리의 주소를 가리키는 역할을 한다. 포인터가 가리키는 주소실제 그 주소의 값은 별개의 값으로 취급해야 함을 명심하자. 예를 들어 포인터가 5번 주소를 가리키고 있다면, 5번 주소의 값은 123 이런식이다.

  1. +++++ +++++
    포인터가 가리키는 주소(0)의 값을 10 증가시켰다. 메모리의 초기값은 0이므로, 최종적으로 포인터가 가리키는 값에 10이 들어간다.
  2. [>+++++ ++ >+++++ +++++ >+++ >+ <<<<
    포인터가 가리키는 주소(0)를 하나씩 증가시키며( > (1) > (2) > (3) > (4) ) 각 주소의 값을 7, 10, 3, 1씩 증가시킨다. 이후 다시 포인터가 가리키는 주소를 0으로 감소시킨다.
  3. -]
    포인터가 가리키는 주소(0)의 값을 1 감소시킨 후, 그 값이 0이 아닐 경우 2.의 [ 로 돌아간다. 즉 10회 루프문이 되며, 메모리의 1~4번째 주소에는 각각 70, 100, 30, 10의 값이 들어가게 된다.
  4. >++ .H
    포인터가 가리키는 주소를 1 증가시키고(1), 주소의 값(=70)에 2를 더한 후(=72) 그 값을 아스키 코드로 출력한다. 72에 대응되는 아스키 코드 문자는 H이다.
  5. >+ . +++++ ++ .. +++ .ello
    포인터가 가리키는 주소를 1 증가시키고(2), 주소의 값(=100)에 1을 더한 후(=101) 한 번 출력, 7을 더한 후(=108) 두 번 출력, 또다시 3을 더한 후(=111) 한 번 출력한다. 101, 108, 108, 111에 대응되는 아스키 코드 문자는 ello이다.
  6. >++++++++++++++.------------.<<+++++++++++++++.>.+++.------.--------.>+., World!
    4~5와 같다. 포인터가 가리키는 주소를 이리저리 바꾸고 그 주소의 값에 숫자를 더하고 빼 가면서 문자를 출력한다. 여기서 , World!가 출력되는 것.

4.2. Hello, world! 노가다 출력

위와는 다르게 이런 식으로 +를 도배해도 출력이 가능하다.아니 왜 이러고 사십니까?

[-] H
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++ .
[-] e
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++ + .
[-] l 2
>++
[<
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++.
[-]
>-]< o
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ +.
[-]
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++.
[-] Space
++++++++++ ++++++++++ ++++++++++ ++.
[-] w
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ +++++++++.
[-] o
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ +.
[-] r
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++.
[-] l
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++.
[-] d
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++
++++++++++ ++++++++++ ++++++++++ ++++++++++ ++++++++++.
[-] !
++++++++++ ++++++++++ ++++++++++ +++.
[-] Lf
++++++++++ +++.
[-]


5. 기타



  • 여기서 브레인퍽 프로그램을 실행할 수 있다. 여기서는 #가 중단점으로 사용된다.


  • 언어 자체가 매우 간단하여 구현이 쉽다. 언어 기반 언어


[1] 어떤 프로그래밍 언어나 추상 기계가 튜링 기계와 동일한 계산 능력을 가진다는 뜻이다. 튜링 기계는 계산 가능한 모든 함수를 계산할 수 있는 추상적 모델을 말하는데, 쉽게 말해서 이상적인 컴퓨터를 생각하면 된다. 한 가지 태클이 걸릴 점은, 현실 역사에선 튜링 기계란 개념이 나온 뒤에 그 개념에 기초해서 컴퓨터가 나왔다는 것.[2] 이 덕분에 별도의 주석 명령어 없이 그냥 평문을 써도 주석이 되는 셈이다.