关于函数指针和指针函数的分析
2016-04-27 19:28
344 查看
关于函数指针和指针函数的分析
指针函数
它本质是一个函数,返回值是某一类型的指针。
看定义,首先它是一个函数,而且它必须有一个返回值,并且该返回值是某一类型的指针。该指针的类型必须与函数类型相同。
定义格式: 类型名 *函数名(函数的参数)
[b] char * strstr(const char *str1,const char *str2);[/b]
由于 * 的优先级低于(),所以函数名strstr先与()结合,表面这是一个函数,再与 * 以及 char 结合,表面该函数的返回值为一个char类型的指针。
注:指针函数的返回值为指针,该指针指向返回值,内部存储的是返回值的地址。
下面看一个例子:
注意:在主函数中应该建立一个同类型的指针来接受这个返回值。
函数指针
顾名思义,它的本质是一个指针,是一个指向函数的指针变量。每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上是大体一致的。
用途:调用函数和做函数的参数。
定义格式:类型名(*指针名)(参数列表)
int (*fun)(int ,int );
同指针函数,* 的优先级小于(),所以用()将 * 和指针变量名fun括起来,表名它是一个指针,再与(int,int)和 int 结合,表名该指针必须指向一个形参是两个整形,并且类型为 int 的函数。
函数指针的赋值方法可以有两种。例如:
注:在赋值时,函数max不带参数,此时max就相当于函数的首地址,fun或fuc就指向max(a,b)这个函数的首地址。
我们还可以用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);
下面看一个函数指针的应用举例:
注: 1、函数指针的类型与其所指向的函数的类型必须相同。
2、函数指针的参数类型,个数必须与其所指向的函数的参数类型,个数相同。
函数指针数组。
这个我们直接看它的标准定义方法:
首先它是一个数组。 数组名[] a[]
这个数组的数据类型为指针。 *数组名[] *a[]
这些指针所指向的对象为某一类型的函数。 类型名 (*数组名[])(形式参数) int(*a[])(int,int)
注:优先级问题这里便不再说,不懂得请向上翻阅,或自行查询资料。
关于函数指针数组的定义方法还有一种叫,蒙骗法。感兴趣的请自己百度。笔者建议大家用标准方法,可读性比较高。
下面来看一个应用举例:
还是上面的例子,我们把它改变一下。
关于定义声明,在这里做一点补充,可以仿照数组初始化方法,
int (*fun[])(int ,int)={max,add};
指向函数指针数组的指针
笔者目前还没用过这种指针,不过我认为指向函数指针数组的指针为一个三级指针。
定义应该类似于
int ***arr=(*fun[])(int,int);
这只是我一时的想法,等我查阅资料后会对该内容做一定补充。
指针函数
它本质是一个函数,返回值是某一类型的指针。
看定义,首先它是一个函数,而且它必须有一个返回值,并且该返回值是某一类型的指针。该指针的类型必须与函数类型相同。
定义格式: 类型名 *函数名(函数的参数)
[b] char * strstr(const char *str1,const char *str2);[/b]
由于 * 的优先级低于(),所以函数名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>
注:在赋值时,函数max不带参数,此时max就相当于函数的首地址,fun或fuc就指向max(a,b)这个函数的首地址。
我们还可以用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);
这只是我一时的想法,等我查阅资料后会对该内容做一定补充。
相关文章推荐
- Android bluetooth介绍(一):基本概念及硬件接口
- [置顶] Unity与Android交互-android的安装与配置
- UC网盘被关停 将与阿里淘盘合并?(案例说明云盘的成本才是重点,技术不是问题;与巨头竞争是重点)
- C++之时间统计
- 解读(三):分析MainActivity, 程序的界面主体框架
- Spring Learning Diary
- 常用的shell命令
- Css外边距合并
- android meta-data
- Struts2返回JSON对象的方法总结
- Apache Storm 2.0.0-SNAPSHOT源码分析笔记(一)
- iOS MRC与ARC 混合编程配置
- php日期函数与php时间函数
- Java实现单点登录
- 奥特曼小分队之四(Work Breakdown Structure)
- Gson进行json字符串和对象之间的转化
- Cocos2dx 代码命名风格
- PAT-B 1007. 素数对猜想
- 关于AS中使用第三方库vitamio的注意事项
- 【密码学】云的MD5破解