为什么我自己做的网站百度不到/搜索百度一下
C语言中的函数指针学习笔记
一、定义函数指针
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
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, 2));
printf("%d\n", 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
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上偶尔看到如下的问题,代码如下
#include
void 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# WinForm国际化实现的简单方法
Android TabWidget切换卡的实现应用
深入Android线程的相关问题解惑
JSP 从配置文件获取参数详解
OracleOraDb10g_home1TNSListener服务无法启动怎么解决
php采用file_get_contents代替使用curl实例
PHP解决URL中文GBK乱码问题的两种方法
Android6.0仿微信权限设置
Win10 14342系统的任务栏和开始菜单属性在哪里?
讲解Java中如何构造内部类对象以及访问对象
原生js编写autoComplete插件
PHP curl实现抓取302跳转后页面的示例
JavaScript数组对象实现增加一个返回随机元素的方法
win7系统安装iTunes遇到错误码2203怎么办?解决方法