C 포인터 원리(41) - 귀속(2)
7615 단어 설계와 구조
dp@dp:~ % gcc bfi.c -o bfi
bfi.c: In function ‘interpret’:
bfi.c:35: warning: incompatible implicit declaration of built-in function ‘exit’
bfi.c:40: warning: incompatible implicit declaration of built-in function ‘exit’
dp@dp:~ %
밑에 헬로.b 고전적인hello,world를 출력합니다:
+++++++++[-]<.>+++++++[-]++++++++[-]
<.>+++++++++++[-]<.>++++++++[-]<.>++++++++[
-]
방금 생성된 bf 언어 해석기로 실행합니다.
dp@dp:~ % ./bfi hello.b
Hello World!
prime.b 지정된 정수 내질수 계산 완료:
===================================================================
======================== OUTPUT STRING ============================
===================================================================
++++++++[-]-]-]-]-]-]-]-]-]-]-]-]-]-]
===================================================================
======================== INPUT NUMBER ============================
===================================================================
cont=1
[
cont=0
,
SUB10
[ not 10
cont=1
=SUB38==
=MUL10===
[>+>+<>[<>-]< dup
+++++++++
[
<<<
[>+>+<>[<>-]< dup
[<>-]
]
<<
RMOVE1
<
[>+
]
<
]
[<>-]<<
===================================================================
======================= PROCESS NUMBER ===========================
===================================================================
==== ==== ==== ====
numd numu teid teiu
==== ==== ==== ====
+
[
DUP
[>+>+<>[<>-]<
+
+<<<<<<<< isprime=1
[
=DUP3=
>>+>+<<<>>>[<<<>>>-]<<<
=DUP2=
[>>+>+<<>>[<<>>-]<<<<
DIVIDES===
[>+>+<>[<>-]< DUP i=div
<<
[
>>>>>+ bool=1
<<<
[>+>+<>[<>-]< DUP
[>>[-]<>
[ IF i=0
<<<<
[>+>+<>[<>-]< i=div
>>>
- bool=0
]
<<<
- DEC i
<<
-
]
+>>[<>-]<<
[-]< CLR div
=END DIVIDES
[>>>>>>[-]<<<<<
<<
[-]>[-]<<<
]
[
<<<<<<
[>>+>+<<>>[<<>>-]<<<
===================================================================
======================== OUTPUT NUMBER ===========================
===================================================================
[>+
[
DUP
[>+>+<>[<>-]<
==MOD10
+++++++++<
[
>>>+<< bool= 1
[>+>[-]<[-] ten = tmp
>[<>-] if ten=0 ten=10
<
]
+++++++++ num=9
[-]< dec num by ten
=RROT
[>+
< [>+
< [>+
[<<>>-]
<
=DIV10==
+++++++++<
[
>>>+<< bool= 1
[>+>[-]<[-] ten = tmp
>[<>>+
]
[<<<>>>-]<<<< copy div to num
[-]< clear ten
=INC1===
]
<
[
=MOVER===
[>+
=ADD48==
+++++++[-]
=PUTC=
<./>
MOVEL2==
[<>-]<
]
++++[-]<.>
===================================================================
=========================== END FOR ===============================
===================================================================
]
<<<<<<<<
[-]<
[-]
<
]
LF==
++++++++++.[-]
방금 컴파일된 bf 언어 해석기로 실행합니다.
dp@dp:~ % ./bfi prime.b
Primes up to: 20
2 3 5 7 11 13 17 19
BF 해석기 분석:
1,main 함수는 BF 언어의 원본 코드 파일을 읽기 전용으로 열고 BF 원본 파일을 바이트에 따라 수조 f에 하나씩 복사하고 문자열의 끝 표지 0을 붙인 다음에 수조 f를 매개 변수로 하여interpret 함수를 호출하여 BF 언어의 원본 코드를 실행합니다.
if((z=fopen(argv[1],“r”))) {
while( (b=getc(z))>0 )
*s++=b;
*s=0;
interpret(f);
}
2. BF 언어의 해석기는 수조를 데이터 중심으로 계산한다. 그의 계산 모델에서 수조를 가리키는 바늘이 필요하다. 이 바늘의 이동과 바늘이 가리키는 내용에 대한 조작을 통해 모든 계산을 완성해야 한다.따라서 프로그램은 시작 부분에서 해석기의 핵심인 수조 a와 f, 데이터 a는 BF 명령이 조작하는 데이터를 저장하고 수조 f는 BF 언어 코드 파일을 저장하며 지침 변수 s는 f수조의 첫 번째 요소를 가리킨다.
char a[5000], f[5000], b, o, *s=f;
3. interpret 함수 해석
이 함수는 BF 언어 해석 실행을 실현하는 관건이다.interpret 함수는 수조 바늘 c(BF 언어 원본 코드에 저장된 수조를 가리키는 것)를 받아들인 다음while 문장을 통해 한 글자씩 BF 원본 코드를 추출합니다. (BF 원본 코드의 모든 문자는 하나의 지령이기 때문입니다.) swith...case...문장 블록을 통해 BF 지령(, +, -,,,,,,, [,])을 판단하고 BF 지령을 실행합니다.
이 명령들은 비점프 명령과 점프 명령으로 나뉜다.
(1) 비점프 명령은 순환을 제외한 다른 기능을 완성했다.예를 들어 이동 바늘(바늘은 변수 p를 가리킨다. 예를 들어 코드의'p-'와'p++'), 대수 그룹(수 그룹은 변수 a를 가리킨다. 예를 들어 코드의'a[p]++'와'a[p]–')의 조작, 출력(코드의'putchar(a[p]), flush(stdout);break;'))및 입력 (코드의 "case","표시된 문장 블록).
void interpret(char *c)
{
char *d; int tmp;
r++;
while( *c ) {
//if(strchr("<>+-,.[]
",c))printf("%c",c);
switch(o=1,*c++) {
case '': p++; break;
case '+': a[p]++; break;
case '-': a[p]--; break;
case '.': putchar(a[p]); fflush(stdout); break;
case ',':
tmp=getchar();
if (tmp == EOF) a[p]=0;
else a[p]=tmp;
…
.................
}
r–;
}
(2) 점프 명령은 순환 기능을 완성했다.순환 지령의 해석 실행 과정에서 귀속 메커니즘을 사용하여 BF 언어의'['와']'지령의 해석을 완성했다.'['는 순환의 시작을 표시하고']'는 순환의 끝을 표시한다. 이것은 순환이 끼워 넣을 수 있고 여러 개의'['와'] 지령으로 여러 층의 순환을 구성할 수 있다는 것을 의미한다.
[
포인터가 가리키는 단원 값이 0이면 대응하는] 명령의 다음 명령으로 뒤로 이동합니다
]
만약 바늘이 가리키는 단원 값이 0이 아니라면, 대응하는 [지령의 다음 지령처로 앞으로 뛰어갑니다
여러 순환이 있을 수 있으므로 이번 순환이 시작되는 []에 해당하는 []를 찾아야 합니다. 순환의 조건은 바늘이 가리키는 단원 값을 통해 결정됩니다. 바늘이 가리키는 내용이 0이면 순환이 끝나고, 그렇지 않으면 순환이 계속됩니다.
아래 문장을 통해 "["의 "]"에 대한 검색을 완료하고 찾는 과정에서 다음에 실행할 BF 명령 지침 (for 순환 문장의 "c++") 을 업데이트합니다.
for( b=1,d=c; b && *c; c++ )
b+=c==’[’, b-=c==’]’;
순환의 끝을 찾은 후 바늘이 가리키는 단원 값 (아래 코드의 "a[p]") 을 판단하고, 단원 값이 0이 되지 않으면 인터프리트 함수를 호출하여 다음 명령을 해석합니다.
while( a[p] )
interpret(d);
순환하는 기호가 대응하지 않는 것을 방지하기 위해서, 예를 들면, 마지막에 순환 종료 표시가 많아졌다"] 는 경우, 프로그램이 비정상적으로 종료됩니다. 아래 코드와 같습니다.
case ‘]’:
puts(“UNBALANCED BRACKETS”), exit(0);
이 두 명령에 대한 설명의 모든 코드는 다음과 같습니다.
void interpret(char *c)
{
char *d; int tmp;
r++;
while( *c ) {
............
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);
.................................
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C 포인터 원리(40) - 반복(1)만약 포인터가 가리키는 단원의 값이 0이 아니라면, 대응하는 [지령의 다음 지령으로 앞으로 이동합니다 int p, r, q; char a[5000], f[5000], b, o, *s=f; void interpret(...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.