一、递归
递归在计算机科学中,是指在函数的定义中使用函数自身的方法,递归是进行循环的一种技巧(在类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
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
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)。