C语言中的函数指针学习笔记

C语言中的函数指针学习笔记,第1张

概述一、定义函数指针return_type(*func_pointer)(parameter_list)普通指针变量的定义int*p;char*pointer;

一、定义函数指针

return_type (*func_pointer)(parameter_List)

普通指针变量的定义

int * p;char * pointer;

类型的限定都在变量前面;
函数指针类型的限定是前后都有,前面是返回类型,后面是输入参数。

利用typedef 可以简化上面的表达方式。

typedef return_type (*FunctionPointer) (parameter_List);FunctionPointer func_pointer;

这样是不是容易读了,和上面的功能一样,定义了一个返回类型为return_type ,输入参数为parameter_List的函数指针。

二、定义返回函数指针的函数
return_type(*function(func_parameter_List))(parameter_List)

方框圈出来的表示返回类型为函数指针,剩下的部分就表示一个function函数,输入参数为func_parameter_List。
它就等价于 FunctionPointer function(func_parameter_List); 。
再看看:

voID ( *signal( int sig,voID (* handler)( int )))( int );

signal是一个返回函数指针的函数,signal的输入为int 变量和一个函数指针。

三、函数指针的使用

#include <stdio.h> int add(int a,int b); voID main() {   int(*fun1)(int a,int b) = add;   int(*fun2)(int a,int b) = &add;   int(*fun3)(int a,int b) = *add;   printf("%d\n",fun1(1,2));   printf("%d\n",fun2(1,fun3(1,2));   char input[10];   gets(input); } int add(int a,int b) {   return a + b; }

函数名会被隐式的转变为指针,前面加*和& *** 作符都不起作用,printf的结果都是3。

四、神奇的代码

int (*(*pf())())(){ return nullptr; }

哇哦,这是个什么函数!画个框框分解它

小框表示返回的是一个函数指针,在圈个大框,又是一个函数指针。
它就表示,pf() 返回的是一个函数指针,这个函数指针对应一个无输入参数的函数:返回值也是函数指针(对应无输入参数的函数,返回值为int类型)。好复杂啊,有点晕!
利用typedef 简化一下。

typedef int(*Fun1) (); typedef Fun1(*Fun2) (); Fun2 pf() {    return nullptr; }

这样看就舒服多了。

五、这又是什么鬼!

(*(voID(*) ())0)();

画个框看看:

小框里代表一个函数指针,常数前面加括号代表类型的强制转换。咦,它把0强制转换成了一个函数指针,并执行!这是什么 *** 作啊!
六、一段验证代码

#include <stdio.h> typedef int Function(int,int); typedef int(*FunctionPointer1) (int,int); typedef FunctionPointer1(*FunctionPointer2) (); int fun1(int a,int b) {   return a + b; } FunctionPointer1 fun2() {   return fun1; } FunctionPointer2 fun3() {   return fun2; } int(*(*fun4())())(int,int) {   return fun2; } voID main() {   Function* fuction = fun1;   FunctionPointer1 fun = fun1;   int a = fun3()()(3,4);   int b = fun4()()(5,6);   printf("%d\n%d\n",a,b);   printf("fun1:%d\n*fun1:%d\n&fun1:%d",fun1,*fun1,&fun1);   printf("fun:%d\n*fun:%d\n&fun:%d",fun,*fun,&fun);   char chars[10];   gets(chars); }

函数名前面加不加*,& *** 作符,都是一个效果;函数指针前面加不加* *** 作符是一个效果,但是加上& *** 作符就代表着取指针的地址了。
可以通过typedef int Function(int,int); 为一种类型的函数定义别名,但是使用的时候只能定义指针形式的变量:

Function* fuction = fun1;

七、一个问题
在stackoverflow上偶尔看到如下的问题,代码如下

#includevoID hello() { printf("hello"); }int hello_1(){    printf("hello 1");    return 0;} int main(voID) {  (*****hello)();  (****hello_1)();}

   执行结果是无论hello前面有多少个指针符号,都是执行hello()函数,打印“hello”。
  为什么出现这样的结果呢:
    用指针指向一个函数是OK的,但是仍然还要被转化为一个function pointer。其实使用*来指向一个函数 == CALL这个函数。因此无论指向多少次,仍然也是调用这个函数。
为什么一个函数会被转化成一个指针呢?答案就是将函数默认的转换成函数指针,可以减少&的使用,编译器默认的将函数转化为函数指针,也省得你每次调用函数时加*调用函数。
  哈哈,也就是我们之前说的,函数即指针。似乎有点不是很清晰,再看下面的例子

voID foo() {    printf("Foo to you too!...\n");}; int a = 2;int* test(){    return &a;}int main(){  int i;  voID (*p1_foo)() = foo;  voID (*p2_foo)() = *foo;  voID (*p3_foo)() = &foo;  voID (*p4_foo)() = *&foo;  voID (*p5_foo)() = &*foo;  voID (*p6_foo)() = **foo;  voID (*p7_foo)() = **********************foo;   (*p1_foo)();  (*p2_foo)();  (*p3_foo)();  (*p4_foo)();  (*p5_foo)();  (*p6_foo)();  (*p7_foo)();  i = *(***test)();printf("i=%d\n",i);}

上面的列子不出例外,都能正常打印我们想要的数据。
但是对于&,则要进行仔细的分析一下:
&对于一个函数的 *** 作,是返回一个指针,指向函数的指针,如果在对此指针执行&也就是&&foo,则会返回error,因为&foo是一个指针数值,也就是一个rvalue类型,再对他进行& *** 作,显然是返回error的。

&&foo  //EROOR&*&*&*&*&*&*foo //OK&******&foo  //OK

总结

以上是内存溢出为你收集整理的C语言中的函数指针学习笔记全部内容,希望文章能够帮你解决C语言中的函数指针学习笔记所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1247091.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存