C指针原理(40)-递归(1)
一、遞歸
遞歸在計算機科學中,是指在函數的定義中使用函數自身的方法,遞歸是進行循環的一種技巧(在類lisp等函數語言中它也是實現循環的主要甚至唯一途徑,比如下面的LISP代碼)。
1、
費波那西數列(意大利語:Successione di Fibonacci),又譯費波拿契數、斐波那契數列、費氏數列、黃金分割數列。
在數學上,費波那西數列是以遞歸的方法來定義:
遞歸是完成費波那西數列計算的方法之一,費波那西數列由0和1開始,之后的費波那西系數就由之前的兩數相加。
、rainfuck解釋器C語言實現
Brainfuck,是一種極小化的計算機語言,它是由Urban Müller在1993年創建的。一種簡單的、可以用最小的編譯器來實現的、符合圖靈完全思想的編程語言。這種語言由八種運算符構成,brainfuck的計算方式如此與眾不同,基于一個簡單的機器模型,除了指令,這個機器還包括:一個以字節為單位、被初始化為零的數組、一個指向該數組的指針(初始時指向數組的第一個字節)、以及用于輸入輸出的兩個字節流。
下面是這八種狀態的描述,其中每個狀態由一個字符標識:
字符
含義
指針加一
<
指針減一
指針指向的字節的值加一
指針指向的字節的值減一
.
輸出指針指向的單元內容(ASCII碼)
,
輸入內容到指針指向的單元(ASCII碼)
[
如果指針指向的單元值為零,向后跳轉到對應的]指令的次一指令處
]
如果指針指向的單元值不為零,向前跳轉到對應的[指令的次一指令處
可在這個頁面找到這個語言的相關內容:http://www.muppetlabs.com/~breadbox/bf/,該網址提供了一個不錯的簡單高效的brainfuck解釋器源代碼,代碼中涉及數組、指針等C指針的應用。
首先,完成這個解釋器,該程序對所需要用到的變量作了如下聲明:
1、數組變量
char a[5000], f[5000]
其中a
#include <stdio.h>
int p, r, q;
char a[5000], f[5000], b, o, *s=f;
void interpret(char *c)
{
char *d; int tmp;
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 ',': tmp=getchar();if (tmp == EOF) a[p]=0; else a[p]=tmp;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);
default: o=0;
}
if( p<0 || p>100)
puts(“RANGE ERROR”), exit(0);
}
r–;
}
int 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);
}
return 0;
}
1、下面的 fib函數是C語言的實現,函數反復調用自身實現計算
執行上述程序:
#include <stdio.h>
long fib_n(long,long,int);
int main(){
fib_n(0, 1, 40);
return 0;
}
int i=0;
long fib_n(long curr,long next,int n) {
printf(“第%d項:%ld\n”,i++,curr);
if (n == 0) {return curr;} else {return fib_n(next, curr+next, n-1);}}
執行程序,main以40為參數n的值,調用fib,fib陸續輸出前41個費波那西系數的值,也是說數列中的41個數(因為第1個數0不是第一項,而是第零項):
dp@dp:~ % gcc fib.c -o fib
dp@dp:~ % ./fib
第0項:0
第1項:1
第2項:1
第3項:2
第4項:3
第5項:5
第6項:8
第7項:13
第8項:21
第9項:34
第10項:55
第11項:89
第12項:144
第13項:233
第14項:377
第15項:610
第16項:987
第17項:1597
第18項:2584
第19項:4181
第20項:6765
第21項:10946
第22項:17711
第23項:28657
第24項:46368
第25項:75025
第26項:121393
第27項:196418
第28項:317811
第29項:514229
第30項:832040
第31項:1346269
第32項:2178309
第33項:3524578
第34項:5702887
第35項:9227465
第36項:14930352
第37項:24157817
第38項:39088169
第39項:63245986
第40項:102334155
其算法可描述如下:
(1)fib函數在數列不為0時,進入遞歸狀態,反復調用自己(也就是fib)。
這個過程雖然調用的都是fib函數,但每次調用的參數都不一定一致辭,因為每次調用函數,都將新的參數傳送給fib函數,每次fib函數的執行需要的參數都是上次fib函數在執行過程中傳遞的。此外,函數的參數傳遞方式是通過函數所屬的堆棧完成的,這意味著雖然遞歸多次反復調用fib函數,但參數只是在本次fib函數執行中用到,使用完畢后堆棧空間就將本次所用的參數釋放。fib對fib自身進行不斷調用(代碼中的“fib_n(next, curr+next, n-1)”),每次調用fib_n函數,curr參數在增長中(curr參數表示數列中的當前項,初始值為0,每次新值為next),而next參數也在增長(next參數表示數列中的下一項,初始值為1,每次新值為curr+next),n參數在減少中(n是一個計數器,注意這個計數器到0才算結束,每次減少1,n初始值為40,n控制了生成的費波那西數列的數的數量)。
(2)在n值等于0時,所有對fib函數的調用結束了,生成的費波那西數的數量達到了程序要求。在數列的開始處(代碼中的“n==0”),最后一次調用fib函數完成,函數返回了程序要求的數列中最后一個數的計算(代碼中的“return curr;”),這時的curr等于102334155)。
總結
以上是生活随笔為你收集整理的C指针原理(40)-递归(1)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C指针原理(39)-GLIB
- 下一篇: Websocket判断逻辑Bug