1. 기본
Brainfuck을 이해하려면 0
각각에 의해 초기화되는 무한한 셀 배열을 상상해야합니다 .
...[0][0][0][0][0]...
brainfuck 프로그램이 시작되면 모든 세포를 가리 킵니다.
...[0][0][*0*][0][0]...
포인터를 오른쪽 >
으로 이동하면 포인터를 X 셀에서 X + 1 셀로 이동하는 것입니다.
...[0][0][0][*0*][0]...
셀 값을 늘리면 +
다음을 얻습니다.
...[0][0][0][*1*][0]...
셀 값을 다시 늘리면 +
다음을 얻습니다.
...[0][0][0][*2*][0]...
셀 값을 줄이면 -
다음을 얻을 수 있습니다.
...[0][0][0][*1*][0]...
포인터를 왼쪽 <
으로 이동하면 포인터를 X 셀에서 X-1 셀로 이동하는 것입니다.
...[0][0][*0*][1][0]...
2. 입력
문자를 읽으려면 쉼표를 사용 ,
합니다. 그것이하는 일 : 표준 입력에서 문자를 읽고 실제 셀에 10 진수 ASCII 코드를 씁니다.
ASCII 테이블을 살펴보십시오 . 예를 들어, 소수점 코드로 !
인 33
반면이 a
있다 97
.
음, BF 프로그램 메모리가 다음과 같다고 상상해 봅시다.
...[0][0][*0*][0][0]...
표준 입력이를 의미한다고 가정하면 a
쉼표 ,
연산자 를 사용하면 BF가 수행하는 작업은 a
10 진수 ASCII 코드 97
를 메모리로 읽는 것입니다 .
...[0][0][*97*][0][0]...
일반적으로 그렇게 생각하고 싶지만 진실은 조금 더 복잡합니다. 진실은 BF는 문자가 아니라 바이트 (그 바이트가 무엇이든)를 읽습니다. 예를 보여 드리겠습니다.
리눅스에서
$ printf ł
인쇄물:
ł
특정 폴란드어 캐릭터입니다. 이 문자는 ASCII 인코딩으로 인코딩되지 않습니다. 이 경우 UTF-8 인코딩이므로 컴퓨터 메모리에서 1 바이트 이상을 차지했습니다. 16 진수 덤프를 만들어 증명할 수 있습니다.
$ printf ł | hd
다음을 보여줍니다.
00000000 c5 82 |..|
0은 오프셋입니다. 82
첫 번째이고 c5
두 번째 바이트를 나타냅니다 ł
(읽기 위해).|..|
이 경우에는 불가능한 그래픽 표현입니다.
글쎄, 당신이 ł
단일 바이트를 읽는 BF 프로그램에 입력으로 전달하면 프로그램 메모리는 다음과 같습니다.
...[0][0][*197*][0][0]...
왜 197
? 음의 197
진수는 c5
진수. 익숙한 것 같습니까? 물론이야. 의 첫 번째 바이트입니다 ł
!
3. 출력
문자를 인쇄하려면 점을 사용합니다 .
. 실제 셀 값을 10 진수 ASCII 코드처럼 취급한다고 가정하면 해당 문자를 표준 출력으로 인쇄합니다.
음, BF 프로그램 메모리가 다음과 같다고 상상해 봅시다.
...[0][0][*97*][0][0]...
이제 도트 (.) 연산자를 사용하면 BF가 수행하는 작업은 다음과 같습니다.
ㅏ
때문에 a
ASCII의 진수 코드입니다 97
.
예를 들어 다음과 같은 BF 프로그램 (97 + 2 개의 점) :
++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++ ..
97까지 가리키는 셀의 값을 증가시키고 2 번 인쇄합니다.
aa
4. 루프
BF에서 루프는 루프 시작 [
과 루프 끝으로 구성됩니다 ]
. 조건이 실제 셀 값인 C / C ++ 에서처럼 생각할 수 있습니다.
아래 BF 프로그램을 살펴보십시오.
++[]
++
실제 셀 값을 두 번 증가시킵니다.
...[0][0][*2*][0][0]...
그리고 []
처럼 while(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)
그러나 우리가 시작한 곳에서 끝내는 것이 좋습니다. 왜 ? 루프가 다른 셀을 끝내면 시작되기 때문에 셀 포인터가 어디에 있을지 추측 할 수 없습니다. 솔직히 말해서,이 연습은 brainfuck을 덜 brainfuck하게 만듭니다.