嵌入式学习笔记十——递归

函数的调用

函数调用的关系:调用者 和被调用者 

这个里面:

int main(void) 
{
   printf("%d\n",getMonthDays()); 
   return 0;
}

main ---成为调用者  ---main函数是整个程序的入口,只能调用者 

getMonthDays --- 在此处是 被调用者

1.函数的嵌套调用

函数不支持嵌套定义,但支持嵌套调用。

函数嵌套调用的过程本质上是利用栈结构的先进后出,保证函数可以层层嵌套调用。

2.栈

栈是一种数据结构(数据结构:表示数组组织形式)

特点: 先进后出 (First In Last Out) //FILO

 c语言角度的栈本质上是一块内存空间,只是按照栈这种数据结构 来处理和使用的

C语言程序:把内存划分了5个区域 

栈:主要用来存放,自动变量或函数调用的数据,栈上变量是自动申请,自动释放的,所以称为自动变量。

堆 :空间大,堆上的空间 ,手动申请,手动释放。栈上定义的指针指向堆上的数据。

字符串常量区 :只读

静态区(全局区) :放全局变量 和 静态变量  

代码区 :只读

栈的大小默认为8M,也可以修改大小,栈被占满后无法再调用函数。

3.函数的递归调用

递归是特殊的嵌套调用:自己调用自己。效果类似循环,但递归是一种特殊的循环。

递归中问题n依赖于问题n-1的解决,要求问题n,就需要解决问题n-1. 

递归代码实现思路:假设要实现递归求1-100的和

1.找递推关系 

怎么从 问题 n 到 问题n-1

  sum(100) => sum(99)+100
  sum(99)  => sum(98)+99
  sum(n) = sum(n-1)+n;

2.找到递推结束条件

n=1

用递归实现1+2+3+...+100:

#include <stdio.h>

int sum(int n)
{
	if(n == 1)
		return 1;
	else
		return sum(n-1) + n;
}

int main(void)
{
	int n;
	scanf("%d",&n);
	int ret = sum(n);
	printf("ret = %d\n",ret);

	return 0;
}

练习:1.求n的阶层2.求斐波拉契数列第n项

#include <stdio.h>

int factorel(int n)//计算阶层
{
	if(n == 1)
		return 1;
	else
		return factorel(n-1) * n;
}

int fibo(int n)//计算斐波拉契数列第n项
{
	if (n == 0)
		return 0;
	if (n == 1||n == 2)
		return 1;
	return fibo(n-1) + fibo(n-2);
	
}


int main(void)
{
	int n;
	scanf("%d",&n);
	int ret = fibo(n);
//  int ret = factrel(n)
	printf("ret = %d\n",ret);

	return 0;
}

数组作为函数参数

1.数组元素作为函数参数

将它当作普通的变量来调用即可

int a[10] = {1,2,3};

int add(int a,int b)
{
   return a + b;
}

add(a[0],a[1]); //

2.数组本身作为函数参数 

在函数中无法计算数组的长度,需要将长度作为参数 传入函数
      形参  --写成数组形式  还需要数组长度 
      实参  --数组名,数组长度

printArrray(int a[],int len) //形参 
//printArrray (int *a,int len) ---编译器最终理解的形式 
//调用
printArray(a,len); 

补充:

int a[10];
数组名 代表类型 ---int[10] 这种数组类型 
数组名 代表的值 ---首元素的地址 //(数组所占内存空间的首地址) 

准备一个数组,实现一个函数,找出最大值:

#include <stdio.h>

void printArray(int a[],int len)//打印数组
{
	int i;
	for (i=0;i<len;++i)
	{
		printf("a[%d] = %d\n",i,a[i]);
	}
}

int findArrayMax(int a[],int len)//找最大值
{
	int i,max;
	max = a[0];
	for (i=1;i<len;++i)
	{
		if (a[i]>max)
			max = a[i];
	}
	return max;
}

int main(void)
{
	int max;
	int a[] = {1,2,3,4,5,6,7,8,9};
	int len = sizeof(a)/sizeof(a[0]);
   
	printArray(a,len);
	max = findArrayMax(a,len);
	printf("max = %d\n",max);
	return 0;
}

总结:

1.设计函数时需要注意能拆成函数的尽量拆成函数,设计时尽可能考虑健壮性、扩展型

2.函数的递归是一个比较难的点,有时候即使有思路也推不出递归的过程,或者看不懂递归的代码,个人感觉递归像是倒过来的循环,前面学的循环是从第一步开始,一步步求解;递归是反过来的,先看到最后一步,再根据递推关系一步步往前推,直到找到第一步,找到递推结束的条件,再求解。

3.在遇到看不懂的递归过程时,可以先带入一个值,将递推关系写出来,一步步往前推,自己动手算算会更容易理解。

  • 16
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值