赞
踩
目录
2.void( * signal ( int,void( * )( int ) ) )( int )
建议在看函数指针前,了解一下数组指针,指针数数组的解析,假如本来就了解的化就可跳过。
其实函数的函数名也是一个地址,就像数组名一样,但&函数名,和函数名单独使用在函数指针时是一样的。
可以实践一下,代码如下。
void test()
{
printf("好好学习,天天编程\n");
}
int main()
{
printf("%p", test);
system("pause");
return 0;
}
那么它肯定可以也有像数组指针一样的类型函数指针。
void (*pfun)();//定义函数指针 void()() 函数声名后面一个括号里放的是参数列表。变量pfun先和*结合,本质是指针。然后 才是void()()函数声名。 则这就是一个函数指针,指针指向的函数无参数,返回值类型为void型。
pfun=test;//把函数的地址赋给函数指针pfun
也可以写成 pfun=&test;
既然知道了函数指针,那么辨析以下有趣的代码。
括号拆分法(*(void(*) ( ) ) 0 )( );
这是《CTraps and Pitfalls》这本经典的书中的一个例子。没有发狂吧?下面我们就来分 析分析:
第一步:void(*)(),可以明白这是一个函数指针类型。这个函数没有参数,没有返回值。
第二步:(void(*)())0,这是将 0 强制转换为函数指针类型,0 是一个地址,也就是说一 个函数存在首地址为 0 的一段区域内。
第三步:(*(void(*)())0),这是取 0 地址开始的一段内存里面的内容,其内容就是保存 在首地址为 0 的一段区域内的函数。
第四步:(*(void(*)())0)(),这是函数调用。
同样也用括号拆分法void( * signal ( int,void( * )( int ) ) )( int )
第一步:signal ( int,void( * )( int ) ),可以明白signal是一个函数名,它有两个参数一个是int,一个是一个void( * )( int )函数指针,且该函数指针指向的是一个匿名函数,该函数参数为int,返回值类型为void型。
第二步:void( * signal ( int,void( * )( int ) ) )( int ),去掉已分析过的黄色部分,可以明白signal函数的返回类型为函数指针类型 void( * )( int ),该返回类型(函数指针)指向的是一个匿名函数,该函数参数为int,返回值类型为void型。
函数指针本质是指针,指针指向的函数由修饰指针的类型所决定。
既然有函数指针,那么就有函数指针数组(与指针数组对比)
int ( * parr [10] )( )
parr与[]先结合,所以本质是数组,数组中存放的是函数指针
函数指针数组的用途:转移表
#include <stdio.h>
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
} int mul(int a, int b)
{
return a*b;
}
int div(int a, int b)
{
return a / b;
}
int main()
{
int x, y;
int input = 1;
int ret = 0;
int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; // 转移表
while (input)
{
printf( "*************************\n" );
printf( " 1:add 2:sub \n" );
printf( " 3:mul 4:div \n" );
printf( "*************************\n" );
printf( "请选择:" );
scanf( "%d", &input);
if ((input < 4 && input > 1))
{
printf( "输⼊入操作数:" );
scanf( "%d %d", &x, &y);
ret = (*p[input])(x, y);
}
else
printf( "输⼊入有误\n" );
printf( "ret = %d\n", ret);
}
return 0;
}
- void test(const char* str)
- {
- printf("%s\n", str);
- }
- int main()
- {
- // 函数指针 pfun
- void (*pfun)(const char*) = test;
- // 函数指针的数组 pfunArr
- void (*pfunArr[5])(const char* str);
- pfunArr[0] = test;
- // 指向函数指针数组 pfunArr 的指针 ppfunArr
- void (*(*ppfunArr)[10])(const char*) = &pfunArr;
- return 0;
- }
- printf("%s\n", str);
- }
- int main()
- {
- // 函数指针 pfun
- void (*pfun)(const char*) = test;
- // 函数指针的数组 pfunArr
- void (*pfunArr[5])(const char* str);
- pfunArr[0] = test;
- // 指向函数指针数组 pfunArr 的指针 ppfunArr
- void (*(*ppfunArr)[10])(const char*) = &pfunArr;
- return 0;
- }
void (* (*ppfunArr)[10] )(const char*)
指针指向一个数组,数组中的每一个元素都是函数指针。
回调函数就是⼀一个通过函数指针调⽤用的函数。如果你把函数的指针(地址)作为参数传递给 另⼀一个函数,当这个指针被⽤用来调⽤用其所指向的函数时,我们就说这是回调函数。回调函数 不不是由该函数的实现⽅方直接调⽤用,⽽而是在特定的事件或条件发⽣生时由另外的一一⽅方调⽤用的,⽤用于对该事件或条件进⾏行行响应。
目前对函数指针的了解大概就这么多,如果学到新的内容会随时更新的。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。