C语言学习第23篇---递归函数理解
递归函数:自己调用自己,是子函数实现的基础。
递归之所以能实现,是因为函数的每个执行过程在栈中都有自己的形参和局部变量的副本,这些副本和该函数的其他执行过程不发生关系
但是递归函数在深层循环时效率很低,所以一般不是必须还是不要使用递归,即使用也不要层次很深
#include<stdio.h>
void DisplayNames(char** cNameArray); /*声明函数*/
char* cNames[]= /*定义字符串数组*/
{
"Aaron", /*为字符串进行赋值*/
"Jim",
"Charles",
"Sam",
"Ken",
"end" /*设定结束标志*/
};
int main()
{
DisplayNames(cNames); /*调用递归函数*/
return 0;
}
void DisplayNames(char** cNameArray)
{
if(*cNameArray=="end") /*判断结束标志*/
{
return ; /*函数结束返回*/
}
else
{
DisplayNames(cNameArray+1); /*调用递归函数*/
printf("%s\n",*cNameArray); /*输出字符串*/
}
}
内部: static 返回值类型 函数名 (参数列表)
#include<stdio.h>
static char* GetString(char* pString) /*定义赋值函数*/
{
return pString; /*返回字符*/
}
static void ShowString(char* pString) /*定义输出函数*/
{
printf("%s\n",pString); /*显示字符串*/
}
int main()
{
char* pMyString; /*定义字符串变量*/
pMyString=GetString("Hello!"); /*调用函数为字符串赋值*/
ShowString(pMyString); /*显示字符串*/
return 0;
}
外部: extern int Add(int iNum1,int iNum2);
外部函数是可以被其他源文件调用的函数
#include<stdio.h>
extern char* GetString(char* pString); /*声明外部函数*/
extern void ShowString(char* pString); /*声明外部函数*/
int main()
{
char* pMyString; /*定义字符串变量*/
pMyString=GetString("Hello!"); /*调用函数为字符串赋值*/
ShowString(pMyString); /*显示字符串*/
return 0;
}
extern void ShowString(char* pString)
{
printf("%s\n",pString); /*显示字符串*/
}
extern char* GetString(char* pString)
{
return pString; /*返回字符*/
}
*********************************************************************************************************************************
分割线
*********************************************************************************************************************************
递归函数的难点在于展开函数不要错误就ok了
void fun(int i)
{
if (i>0)
{
fun(i/2);
}
printf("%d\n",i);
}
int main()
{
fun(10);
return 0;
}
/*
0
1
2
5
10
*/
展开之后
void fun(int i)
{
if (i>0)
{
//fun(i/2);
if(i/2>0)
{
if(i/4>0)
{
…
}
printf("%d\n",i/4);
}
printf("%d\n",i/2);
}
printf("%d\n",i);
}
利用递归函数解决问题
不使用任何变量编写 strlen 函数-------字符串统计函数
int my_strlen( const char* strDest )
{
assert(NULL != strDest); //使用assert宏做入口参数
if ('\0' == *strDest) //确定参数传递过来的地址上的内存存储是否为‘\0’.
{
return 0; //如果是,表明这个是空字符,或者是字符串的结束标志
}
else
{
return (1 + my_strlen(++strDest)); //如果不是,说明地址上存储的是一个字符,计数为char类型元素1,然后在调用函数本身,循环,知道出现0,递归停止。
}
}
***
更简单的程序
int my_strlen( const char* strDest )
{
return *strDest?1+strlen(strDest+1):0;
}
没有做参数入口校验,虽然简洁但是不是很规范,改进之后为
int my_strlen( const char* strDest )
{
assert(NULL != strDest);
return ('\0' != *strDest)?(1+my_strlen(strDest+1)):0;
}
--------------------------------------------------------------------------------------------------------------------------------
递归函数实现阶乘;
#include<stdio.h>
int factorial(int n){
if (n < 0)
return -1; /*Wrong value*/
if (n == 0)
return 1; /*Terminating condition*/
return (n * factorial(n - 1));}
void main() {
int fact = 0;
fact = factorial(5);
printf("\n factorial of 5 is %d \n", fact);
}
/*
factorial of 5 is 120
*/