递归函数和函数指针
递归函数
- 通俗点讲就是自己调用自己
- 但是可不是无限哦
int TotalNum(int a)
{
printf("a=%d\n", a);
if (a <= 1)
{
return 1;
}
return a * TotalNum(a-1);//注意这里如果是--a 或者a--会影响结果
}
int main()
{
int sum = TotalNum(5);//5!5的阶乘
printf("sum=%d\n", sum);
}
注意:
1.递归必须有一个结束条件,否则会无限递归 导致栈溢出
比较:
其实这种递归我们还可以用循环来写
int main()
{
int iBase = 5;
int sum = 1;//5!5的阶乘
while (iBase >= 1)//这里的退出条件 就相当于我们上面的递归
{
sum *= iBase;
iBase--;
}
printf("sum=%d\n", sum);
}
2.尽管递归是自己调用自己 但是有一个特性是 ,必然有一次是其他调用方来触发的这个递归函数
3.这个对于我们再逆向找数据有着很大的帮助
函数指针(指针函数)
1.一个函数总是占用一段连续的内存区域,函数名在表达式中有时也会被转换为该函数所在内存区域的首地址,这和数组名非常类似。
我们可以把函数的这个首地址(或称入口地址)赋予一个指针变量,使指针变量指向函数所在的内存区域,然后通过指针变量就可以找到并调用该函数。
这种指针就是函数指针。
2.我们看看函数指针类型的格式
函数返回值类型 (* 指针变量名) (函数参数列表);
int (* Function)(int * ,float *);
3.看起来是不是有点变扭,别担心我们一一讲解
函数返回值类型”表示该指针变量可以指向具有什么返回值类型的函数;
“函数参数列表”表示该指针变量可以指向具有什么参数列表的函数。这个参数列表中只需要写函数的参数类型即可。为了是表面类型而不是实际的传值
int ADD(int a,int b)
{
return a+b;
}
int (* AddPtrFunction)(int ,int )=ADD;
AddPtrFunction(1,2);//使用函数指针来调用
注意:
函数指针的定义就是将“函数声明”中的“函数名”改成“(*指针变量名)”。但是这里需要注意的是:“(指针变量名)”两端的括号不能省略,括号改变了运算符的优先级。如果省略了括号,就不是定义函数指针而是一个函数声明了,即声明了一个返回值类型为指针型的函数。
4.继续观察,有人会发现似乎每次要使用函数指针都会写这么“int ( AddPtrFunction)(int ,int )”一长串代码,有没有简单的呢?
5.当然是有的,这里就要介绍一下typedef,其作用是用来给我们的类型 取一个别名
typdedef int (* AddPtrFunctionType)(int ,int );
6.此时我们发现int (* AddPtrFunction)(int ,int )里面的AddPtrFunction指针变量名变成了AddPtrFunctionType(这个是自定义的,为了方便讲解说明在后面加了Type,来说明是个类型了,就不是变量名了)
7.那么我们以后用这种类型的函数就可以使用AddPtrFunctionType函数指针类型来定义一个函数指针变量了
int ADD(int a,int b)
{
return a+b;
}
typedef int (* AddPtrFunctionType)(int ,int );
AddPtrFunctionType AddPtrFunction=ADD;//定义了一个函数指针类型的指针变量
AddPtrFunction(1,2);//使用函数指针来调用
迪大交流群:285530835