关于函数指针和指针函数的分析
指针函数
它本质是一个函数,返回值是某一类型的指针。
看定义,首先它是一个函数,而且它必须有一个返回值,并且该返回值是某一类型的指针。该指针的类型必须与函数类型相同。
定义格式: 类型名 *函数名(函数的参数)
char * strstr(const char *str1,const char *str2);
由于 * 的优先级低于(),所以函数名strstr先与()结合,表面这是一个函数,再与 * 以及 char 结合,表面该函数的返回值为一个char类型的指针。
注:指针函数的返回值为指针,该指针指向返回值,内部存储的是返回值的地址。
下面看一个例子:
<span style="font-size:18px;">#include<stdio.h>
#include<assert.h>
char *my_strcat( char *dest, const char *src)
//学会用const保护参数
{
assert(*dest!=NULL);
assert(*src!=NULL);
//assert判断*dest与*src是不是为空,若为空,以下程序则不再执行。
char*tmp=dest;
//建立一个指针变量保存原指针的地址
while(*dest)
{
dest++;
}
while(*dest++=*src++)
{
;
}
return tmp;//最后返回一个类型为char*的指针
//dest一直在++,最后变成‘\0’,所以返回时要注意不能再返回dest(return dest)
}
int main()
{
char arr[20]="Hello";
//定义时一定要注意空间问题,原数组空间一定要大于等于拷贝后的空间,不然可能会造成越界。
char arr2[]="bit";
char *tmp=my_strcat(arr,arr2);//这里同样用一个char*的指针来接受这个返回值。
printf("%s",tmp);
return 0;
}</span>
注意:在主函数中应该建立一个同类型的指针来接受这个返回值。
函数指针
顾名思义,它的本质是一个指针,是一个指向函数的指针变量。
每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上是大体一致的。
用途:调用函数和做函数的参数。
定义格式:类型名(*指针名)(参数列表)
int (*fun)(int ,int );
同指针函数,* 的优先级小于(),所以用()将 * 和指针变量名fun括起来,表名它是一个指针,再与(int,int)和 int 结合,表名该指针必须指向一个形参是两个整形,并且类型为 int 的函数。
函数指针的赋值方法可以有两种。例如:
<span style="font-size:18px;">int max(int a,int b);
int (*fun)(int ,int );
int (*fuc)(int,int);
fun=max;// 1
fuc=&max;// 2</span>
我们还可以用typedef来声明函数指针。
1、先用typedef来定义函数指针类型。
tepydef int(*fun)(int ,int );
2、当我们以后多次用到函数指针时可以直接用fun定义声明。
fun max_u=max(int a,int b);
fun add_u=add(int a,int b);
下面看一个函数指针的应用举例:
<span style="font-size:18px;">#include<stdio.h>
typedef int(*fun)(int ,int );//typedef定义完之后一定要加分号
int add(int a,int b)
{
int c=a+b;
return c;
}
int max(int x,int y)
{
return x>y?x:y;
}
int main()
{
fun max_u=max;//直接用fun来定义函数指针
fun add_u=add;
printf("%d %d",max_u(1,2),add_u(1,2));
return 0;
}</span>
注: 1、函数指针的类型与其所指向的函数的类型必须相同。
2、函数指针的参数类型,个数必须与其所指向的函数的参数类型,个数相同。
函数指针数组。
这个我们直接看它的标准定义方法:
首先它是一个数组。 数组名[] a[]
这个数组的数据类型为指针。 *数组名[] *a[]
这些指针所指向的对象为某一类型的函数。 类型名 (*数组名[])(形式参数) int(*a[])(int,int)
注:优先级问题这里便不再说,不懂得请向上翻阅,或自行查询资料。
关于函数指针数组的定义方法还有一种叫,蒙骗法。感兴趣的请自己百度。笔者建议大家用标准方法,可读性比较高。
下面来看一个应用举例:
还是上面的例子,我们把它改变一下。
<span style="font-size:18px;">#include<stdio.h>
int add(int a,int b)
{
int c=a+b;
return c;
}
int max(int x,int y)
{
return x>y?x:y;
}
int main()
{
int (*fun[2])(int,int);//定义一个函数指针数组
fun[0]=max;//赋值
fun[1]=add;
printf("%d %d",fun[0](1,2),fun[1](1,2));//调用
return 0;
}</span>
关于定义声明,在这里做一点补充,可以仿照数组初始化方法,
int (*fun[])(int ,int)={max,add};
指向函数指针数组的指针
笔者目前还没用过这种指针,不过我认为指向函数指针数组的指针为一个三级指针。
定义应该类似于
int ***arr=(*fun[])(int,int);
这只是我一时的想法,等我查阅资料后会对该内容做一定补充。