C语言中的函数指针和左右法则
2016-08-17 23:11
267 查看
1、一个普通的函数调用例子
这个MyFun函数是一个无返回值的函数,它并不完成什么事情,只是一个普通的函数,在主函数中进行调用,主函数调用MyFun函数的书写格式为: MyFun(10);
我们一开始只是从功能上或者说从数学意义上理解MyFun这个函数,知道MyFun函数名代表的是一个功能(或是说一段代码)。但是直到学习了函数指针的概念后,不得不思考函数名到底是什么东西呢??(可能你觉得这没有什么意义,不要着急,继续向下看。)
函数指针变量的申明:就象某一数据变量的内存地址可以存储在相应的指针变量中一样,函数的首地址也可以存储在某个函数指针变量里面,这样,我们就可以通过这个函数指针变量来调用所指向的函数了。
在C系列语言中,任何一个变量,总是要先申明,之后才能使用的,那么,函数指针变量也应该要先申明吧?那又是如何来申明呢?以上面的例子为例,我来申明一个可以指向MyFun函数的函数指针变量FunP,下面就是申明FunP变量的方法:
void (*FunP)(int) ; //也可写成void (*FunP)(int x);
通过上面的申明可知,整个函数指针变量的申明格式如同函数MyFun的申明处一样,只不过——我们把MyFun改成(*FunP)而已,这样就有了一个能指向MyFun函数的指针FunP了。(当然,这个FunP指针变量也可以指向所有其它具有相同参数及返回值的函数)
2、通过函数指针变量调用函数
有了FunP指针变量后,我们就可以对它赋值指向MyFun,然后通过FunP来调用MyFun函数了。看我如何通过FunP指针变量来调用MyFun函数的:
运行上面的例子,通过函数指针可以准确无误的调用MyFun函数。
通过上面的例子,我们就会想——MyFun与FunP的类型关系类似于int 与int 的关系??函数MyFun好像是一个如int的变量(或常量),而FunP则像一个如int 一样的指针变量!!
好像可以类似,其实不然,通过函数指针调用函数还有其他的书写格式,来完成同样的事情,如下几种书写格式:
代码之一:
运行这个例子,准确无误的得到与上面例子同样的结果,上面的例子中出现语句:FunP=MyFun; 这就有点糊涂了,这样将MyFun值同赋值给FunP,难道MyFun与FunP是同一数据类型(即如同的int 与int的关系),而不是如同int 与int*的关系了?暂时不解释,先看看下面的代码:
代码之二:
代码之三:
将以上两段代码分别运行,得到的结果与前面两个例子运行的结果一致。
还有下面的例子,运行也没有问题吆!!
你也许第一次见到吧:函数名调用也可以是这样写的啊!(只不过我们平常没有这样书写罢了)
那么,这些又说明了什么呢?可以的得到以下结论:
(1)、其实,MyFun的函数名与FunP函数指针都是一样的,即都是函数指针。MyFun函数名是一个函数指针常量,而FunP是一个函数数指针变量,这是它们的关系。
(2)、但函数名调用如果都得如(*MyFun)(10),这样,那书写与读起来都是不方便和不习惯的。所以C语言的设计者们才会设计成又可允许MyFun(10)这种形式地调用(这样方便多了并与数学中的函数形式一样,不是吗?)
(3)、为统一起见,FunP函数指针变量也可以FunP(10)的形式来调用。
(4)、赋值时,即可FunP=&MyFun形式,也可FunP=MyFun。
上述代码的书写格式,随你的喜好写成什么形式都可以!!
但是有一点需要格外注意,如下:
//自行包含头文件 void MyFun(int x); //此处的申明也可写成:void MyFun( int ); int main(int argc, char* argv[]) { MyFun(10); //这里是调用MyFun(10);函数 return 0; } void MyFun(int x) //这里定义一个MyFun函数 { printf(“%d\n”,x); }
这个MyFun函数是一个无返回值的函数,它并不完成什么事情,只是一个普通的函数,在主函数中进行调用,主函数调用MyFun函数的书写格式为: MyFun(10);
我们一开始只是从功能上或者说从数学意义上理解MyFun这个函数,知道MyFun函数名代表的是一个功能(或是说一段代码)。但是直到学习了函数指针的概念后,不得不思考函数名到底是什么东西呢??(可能你觉得这没有什么意义,不要着急,继续向下看。)
函数指针变量的申明:就象某一数据变量的内存地址可以存储在相应的指针变量中一样,函数的首地址也可以存储在某个函数指针变量里面,这样,我们就可以通过这个函数指针变量来调用所指向的函数了。
在C系列语言中,任何一个变量,总是要先申明,之后才能使用的,那么,函数指针变量也应该要先申明吧?那又是如何来申明呢?以上面的例子为例,我来申明一个可以指向MyFun函数的函数指针变量FunP,下面就是申明FunP变量的方法:
void (*FunP)(int) ; //也可写成void (*FunP)(int x);
通过上面的申明可知,整个函数指针变量的申明格式如同函数MyFun的申明处一样,只不过——我们把MyFun改成(*FunP)而已,这样就有了一个能指向MyFun函数的指针FunP了。(当然,这个FunP指针变量也可以指向所有其它具有相同参数及返回值的函数)
2、通过函数指针变量调用函数
有了FunP指针变量后,我们就可以对它赋值指向MyFun,然后通过FunP来调用MyFun函数了。看我如何通过FunP指针变量来调用MyFun函数的:
//自行包含头文件 void MyFun(int x); //这个申明也可写成:void MyFun( int ); void (*FunP)(int ); //也可申明成void(*FunP)(int x),但习惯上一般不这样。 int main(int argc, char* argv[]) { MyFun(10); //这是直接调用MyFun函数 FunP=&MyFun; //将MyFun函数的地址赋给FunP变量 (*FunP)(20); //这是通过函数指针变量FunP来调用MyFun函数的 return 0; } void MyFun(int x) //这里定义一个MyFun函数 { printf(“%d\n”,x); }
运行上面的例子,通过函数指针可以准确无误的调用MyFun函数。
通过上面的例子,我们就会想——MyFun与FunP的类型关系类似于int 与int 的关系??函数MyFun好像是一个如int的变量(或常量),而FunP则像一个如int 一样的指针变量!!
int i,*pi; pi=&i; //与FunP=&MyFun比较
好像可以类似,其实不然,通过函数指针调用函数还有其他的书写格式,来完成同样的事情,如下几种书写格式:
代码之一:
//自行包含头文件 void MyFun(int x); void (*FunP)(int ); //申明一个用以指向同样参数,返回值函数的指针变量 int main(int argc, char* argv[]) { MyFun(10); //这里是调用MyFun(10)函数 FunP=MyFun; //将MyFun函数的地址赋给FunP变量 FunP(20); //这是通过函数指针变量来调用MyFun函数 return 0; } void MyFun(int x) //这里定义一个MyFun函数 { printf(“%d\n”,x); }
运行这个例子,准确无误的得到与上面例子同样的结果,上面的例子中出现语句:FunP=MyFun; 这就有点糊涂了,这样将MyFun值同赋值给FunP,难道MyFun与FunP是同一数据类型(即如同的int 与int的关系),而不是如同int 与int*的关系了?暂时不解释,先看看下面的代码:
代码之二:
//自行包含头文件 void MyFun(int x); void (*FunP)(int ); //申明一个用以指向同样参数,返回值函数的指针变量 int main(int argc, char* argv[]) { MyFun(10); //这里是调用MyFun(10)函数 FunP=&MyFun; //将MyFun函数的地址赋给FunP变量 FunP(20); //这是通过函数指针变量来调用MyFun函数 return 0; } void MyFun(int x) //这里定义一个MyFun函数 { printf(“%d\n”,x); }
代码之三:
//自行包含头文件 void MyFun(int x); void (*FunP)(int ); //申明一个用以指向同样参数,返回值函数的指针变量 int main(int argc, char* argv[]) { MyFun(10); //这里是调用MyFun(10)函数 FunP=MyFun; //将MyFun函数的地址赋给FunP变量 (*FunP)(20); //这是通过函数指针变量来调用MyFun函数 return 0; } void MyFun(int x) //这里定义一个MyFun函数 { printf(“%d\n”,x); }
将以上两段代码分别运行,得到的结果与前面两个例子运行的结果一致。
还有下面的例子,运行也没有问题吆!!
//自行包含头文件 void MyFun(int x); //此处的申明也可写成:void MyFun( int ); int main(int argc, char* argv[]) { (*MyFun)(10); //看,函数名MyFun也可以有这样的调用格式 return 0; } void MyFun(int x) //这里定义一个MyFun函数 { printf(“%d\n”,x); }
你也许第一次见到吧:函数名调用也可以是这样写的啊!(只不过我们平常没有这样书写罢了)
那么,这些又说明了什么呢?可以的得到以下结论:
(1)、其实,MyFun的函数名与FunP函数指针都是一样的,即都是函数指针。MyFun函数名是一个函数指针常量,而FunP是一个函数数指针变量,这是它们的关系。
(2)、但函数名调用如果都得如(*MyFun)(10),这样,那书写与读起来都是不方便和不习惯的。所以C语言的设计者们才会设计成又可允许MyFun(10)这种形式地调用(这样方便多了并与数学中的函数形式一样,不是吗?)
(3)、为统一起见,FunP函数指针变量也可以FunP(10)的形式来调用。
(4)、赋值时,即可FunP=&MyFun形式,也可FunP=MyFun。
上述代码的书写格式,随你的喜好写成什么形式都可以!!
但是有一点需要格外注意,如下:
void MyFun(int); //不能写成void (*MyFun)(int); void (*FunP)(int); //不能写成void FunP(int);
相关文章推荐
- 深入学习C语言中的函数指针和左右法则
- 水滴石穿C语言之指针、数组和函数(转载)
- 水滴石穿C语言之指针、数组和函数
- 关于C语言中的函数指针
- C指针声明解读之左右法则
- C语言指针,malloc.h函数使用
- C语言之函数指针
- C语言之指针、数组和函数
- C语言之指针、数组和函数(转)
- 水滴石穿C语言之指针、数组和函数
- 用指针处理C语言中不定数目的函数参数
- 用C语言来实现的类似C++函数的重载特性-----void*指针闲谈
- 水滴石穿C语言之指针、数组和函数
- C指针声明解读之左右法则
- C语言之指针、数组和函数
- C语言之指针、数组和函数
- C语言之指针、数组和函数
- (不错)C语言教程之十七:指针函数和函数指针
- 深入理解C语言中的指向函数的指针和返回指针的函数!
- 指针的概念、C指针声明解读之左右法则