递归指的是在函数的定义中使用函数自身的方法。
void func(int)
{
/* 代码 */
func(/* 参数 */) //函数调用自己
}
C 语言支持递归,即一个函数可以调用其自身。但在使用递归时,程序员需要注意定义一个从函数退出的条件,否则会进入死循环。
递归是一个简洁的概念,同时也是一种很有用的手段。但是,使用递归是要付出代价的。与直接的语句(如while循环)相比,递归函数会耗费更多的运行时间,并且要占用大量的栈空间。递归函数每次调用自身时,都需要把它的状态存到栈中,以便在它调用完自身后,程序可以返回到它原来的状态。
采用递归方法来解决问题,必须符合以下三个条件:
- 可以把要解决的问题转化为一个新问题,而这个新的问题的解决方法仍与原来的解决方法相同,只是所处理的对象是有规律的。
说明:解决问题的方法相同,调用函数的参数每次不同(有规律),如果没有规律也就不能适用递归调用。 - 可以应用这个转化过程使问题得到解决。
- 必定要有一个明确的结束递归的条件,不然可能导致系统崩溃。
例如求阶乘
不使用递归
long long func(int n)
{
if(n < 0)
return -1;
else if(n == 0)
return 1;
else
{
long long sum = 1;
for(int i = 2; i <= n; i++)
sum *= i;
return sum;
}
}
使用递归
long long func(int n)
{
if(n < 0)
return -1;
else if(n == 0)
return 1;
else
return n * func(n - 1);
}
10进制转换为 2进制
void func(unsigned int n)
{
if(n)
{
func(n / 2);
printf("%d", n % 2);
}
}
求一个整型类型的数据各个位上的数字之和,比如int i = 123;
,输出应为6
unsigned func(int n)
{
if(n)
{
return n % 10 + func1(n / 10);
}
return 0;
}
在递归函数中使用静态变量
由于静态变量在程序开始运行时系统就分配了一块内存空间给他,直到整个程序结束才被释放掉。所以以下递归函数在进入函数时为静态变量开辟了内存空间,在递归调用的过程中,不会再开辟新的内存空间,而是对原有内存空间的操作。
我们可以使用静态变量来记录递归次数
unsigned func(int n)
{
static unsigned int count = 0;
count++;
if(n)
{
printf("%u\n", count);//输出递归次数
return func(n / 10) + n % 10;
}
return 0;
}