递归函数
编程语言中,函数Func(Type a,……)直接或间接调用函数本身,则该函数称为递归函数。递归函数不能定义为内联函数。——百度百科
但要满足两个条件:1.必须要有一个递归条件 2.函数执行一次应该接近递归条件。(容易写出死递归)
一个简单的函数死递归
int main()
{
printf("hello c \n");
main();
return 0;
}
如上无限调用main函数。
一个正常递归函数写法
void print(int a)
{
if (a > 9) //**递归条件**//
print(a / 10);//不断逼近递归条件
printf("%d ", a % 10);
}
int main()
{
int a = 1234;
print(a);
/*printf("hello c \n");
main();*/
return 0;
}
递归函数可能会造计算资源的浪费
例如:计算第n个斐波那契数。
int Fib(int n)
{
if(n<=2)
return 1;
else
return Fib(n-1)+Fib(n-2);
}
int main()
{
int n;
scanf("%d",&n)
int fib=Fib(n);
printf("%d",fib);
return 0;
}
当计算第50个斐波那契数时计算的结果相当慢的
分析:
计算第50个斐波那契数 | 当计算第50个斐波那契数时你得知道第49,48数字。 |
计算第49个斐波那契数 | 当计算第49个斐波那契数时你得知道第48,47数字。 |
计算第48个斐波那契数 | 当计算第48个斐波那契数时你得知道第47,46数字。 |
计算第n个斐波那契数 | ... |
由此我们可以看出中间由大量的重复计算。
函数调用
传值,是把值传过去,函数里的参数是实际参数的一份拷贝,因此你在函数里改变参数是不会影响实际变量a,b的值。
例如
...
int Add(int x,int y)
{
return x+y;
}
int main()
{
int a=10;
int b=13;
int ret=Add(a,b);//这里只是把a,b的值传过去
return 0;
}
传址,是把地址作为参数传递给函数,在函数里是可以通过地址找回变量,因此传址时在函数里面改变参数会影响实际变量a,b的值。
例如
...
int Add(int* x,int* y)
{
return x+y;
}
int main()
{
int a=10;
int b=13;
int ret=Add(&a,&b);//这里只是把a,b的地址传过去
return 0;
}
传址于传值的区别例子:
int Add1(int* x,int* y)
{
*x = 20;
*y = 12;
int z = *x + *y;
return z;
}
int Add2(int x,int y)
{
return x + y;
}
int main()
{
int a = 10;
int b = 2;
int ret2 = Add2(a, b);/****传值调用****/
int ret = Add1(&a,&b);/****传址调用****/
printf("%d\n", ret2);
printf("%d", ret);
}
int Add1(int* x,int* y)
{
*x = 20;
*y = 12;
int z = *x + *y;
return z;
}
int Add2(int x,int y)
{
return x + y;
}
int main()
{
int a = 10;
int b = 2;
int ret = Add1(&a,&b);/****传址调用****/
int ret2 = Add2(a, b);/****传值调用****/
printf("%d\n", ret2);
printf("%d", ret);
}
运行上面两种写法的代码,发现得出两种不同的结果,且经过调试发现传址确实会改变函数外部变量值。