C指针原理(40)-递归(1)

版权声明:本博客所有文章版权归博主刘兴所有,转载请注意来源 https://blog.csdn.net/AI_LX/article/details/89412825

一、递归

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

猜你喜欢

转载自blog.csdn.net/AI_LX/article/details/89412825