指针函数
概述
含义:指针函数就是返回指针的函数
定义:<类型>* <函数名>(形参)
注意点:返回的指针,指向的位置不能为栈空间,即:不能指向函数退出后被释放的空间位置。
返回值注意点
可以作为指针函数的返回值的如下:
1、全局变量的地址
2、字符串常量的地址
3、函数中static修饰的局部变量地址
4、动态申请的堆的地址
5、主调函数中传入的地址
函数指针
1、函数指针
函数指针是指向函数入口地址的指针。对于函数,函数名就是函数的入口地址。
形式:<返回值类型>(*指针名)(形参)
赋值:p = 函数名
调用:p() 或 (*p)()
注意:函数指针的返回值类型、形参要与指向的函数一致
代码示例1: 函数指针的使用
代码示例2:函数指针传参(不改变值)
代码示例3:函数指针传参(改变值)
2、函数指针数组
函数指针数组是一个一维数组,所有操作与数组一致,只是元素变为了函数指针。
形式:<返回值类型>(*指针名[数组大小])(形参) 就是比函数指针定义多了红色的部分
示例代码:遍历输出函数
递归函数
递归函数就是函数内部调用了自己的函数。递归函数必须有一个停止条件,否则将会变成死循环。
注意:递归函数中只编写算法,不进行数据存储。存储函数通过调用递归函数获取返回值,之后进行存储。
编写思路:
- 递推的方法找规律,找出 y(x)= g(x),g(x)中包含y(x) 这种表达式
- 找到停止条件,即y(x)函数传入的x为某个值时,x=常数
练习2:编写n!函数
1、确定函数:n!函数,阶乘就是一个函数,命名为fac(n)。
2、递推方法找规律:5!= 5*4*3*2*1 = 5*4!,一般式为fac(n) = n*fac(n-1);
3、找到停止条件:1! = 1,而不是1*0!,所以n = 1为停止条件
代码实现如下:
#include <stdio.h>
int fac(int n){
//1.停止条件
if(n==1){
return 1;//这就是fac(1) = 1那个停止条件
}else{
return n*fac(n-1);//这就是fac(n) = n*fac(n-1)那个一般式
}
}
int main(){
printf("%d\n",fac(5));
return 0;
}
练习2:编写斐波那契打印函数
已知斐波那契的递推定义为:f(0)=1,f(1)=1,f(n)=f(n-1)+f(n-2)(n≥2)
斐波那契数列值为:1、1、2、3、5、8、13、21、34
1、确定函数:斐波那契计算函数f(x),打印函数用数组打印。
2、递推方法找规律:f(n)=f(n-1)+f(n-2)(n≥2)
3、找到停止条件:f(0)=1,f(1)=1
代码实现如下:
#include <stdio.h>
//#define NDEBUG
#include <assert.h>
//计算斐波那契
int f(int x);
//总调用函数
char* get_f(int x);
//打印数组
void Array1Print(char* array,int size);
int main(){
int x = 8;
Array1Print(get_f(x),x);
return 0;
}
//计算斐波那契
int f(int x){
//1.停止条件
if(x==1||x==0){
return 1;
}else{
return f(x-1)+f(x-2);//f(n)=f(n-1)+f(n-2)
}
}
//总调用函数
char* get_f(int x){
int i;
char* heap = NULL;
char* point = NULL;
heap = (char*)malloc(sizeof(char)*x);
assert(!(heap == NULL));
point = heap;
//循环调用,存储斐波那契值
for(i=1;i<=x;i++){
*point = f(i);
point++;
}
return heap;
}
//打印数组
void Array1Print(char* array,int size){
int i;
for(i=0;i<size;i++){
printf("%d ",array[i]);
}
}