当前位置:   article > 正文

函数指针、函数指针数组、指向函数指针数组的指针_函数指针指向函数数组

函数指针指向函数数组

目录

一、函数指针(本质是指针)

1.( * ( void( * )( ) )0)( ) ;

2.void( * signal ( int,void( * )( int ) ) )( int )

二、函数指针数组 (本质是数组)

三、指向函数指针数组的指针(本质上是一个指针)

4.回调函数


建议在看函数指针前,了解一下数组指针,指针数数组的解析,假如本来就了解的化就可跳过。

点击打开链接

一、函数指针(本质是指针

其实函数的函数名也是一个地址,就像数组名一样,但&函数名,和函数名单独使用在函数指针时是一样的。

可以实践一下,代码如下。

void test()
{
	printf("好好学习,天天编程\n");
}

int main()
{
	printf("%p", test);
	system("pause");
	return 0;
}

那么它肯定可以也有像数组指针一样的类型函数指针。

void (*pfun)();//定义函数指针     void()() 函数声名后面一个括号里放的是参数列表。变量pfun先和*结合,本质是指针。然后                                                才是void()()函数声名。  则这就是一个函数指针,指针指向的函数无参数,返回值类型为void型。

pfun=test;//把函数的地址赋给函数指针pfun

也可以写成 pfun=&test;

既然知道了函数指针,那么辨析以下有趣的代码。

1.( * ( void( * )( ) )0)( ) ;

括号拆分法(*(void(*) ( ) ) 0 )( );

这是《CTraps and Pitfalls》这本经典的书中的一个例子。没有发狂吧?下面我们就来分 析分析:
第一步:void(*)(),可以明白这是一个函数指针类型。这个函数没有参数,没有返回值。
第二步:(void(*)())0,这是将 0 强制转换为函数指针类型,0 是一个地址,也就是说一 个函数存在首地址为 0 的一段区域内。
第三步:(*(void(*)())0),这是取 0 地址开始的一段内存里面的内容,其内容就是保存 在首地址为 0 的一段区域内的函数。

第四步:(*(void(*)())0)(),这是函数调用。

2.void( * signal ( int,void( * )( int ) ) )( int )

同样也用括号拆分法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; 
}

三、指向函数指针数组的指针(本质上是一个指针)

  1. void test(const char* str) 
  2. {
  3. printf("%s\n", str); 
  4. int main() 
  5. {   
  6. // 函数指针 pfun    
  7. void (*pfun)(const char*) = test;    
  8. // 函数指针的数组 pfunArr    
  9. void (*pfunArr[5])(const char* str);   
  10. pfunArr[0] = test;  
  11. // 指向函数指针数组 pfunArr 的指针 ppfunArr    
  12. void (*(*ppfunArr)[10])(const char*) = &pfunArr; 
  13. return 0
  14. }
  15. printf("%s\n", str); 
  16. int main() 
  17. {   
  18. // 函数指针 pfun    
  19. void (*pfun)(const char*) = test;    
  20. // 函数指针的数组 pfunArr    
  21. void (*pfunArr[5])(const char* str);   
  22. pfunArr[0] = test;  
  23. // 指向函数指针数组 pfunArr 的指针 ppfunArr    
  24. void (*(*ppfunArr)[10])(const char*) = &pfunArr; 
  25. return 0
  26. }

void (* (*ppfunArr)[10] )(const char*)

指针指向一个数组,数组中的每一个元素都是函数指针。

4.回调函数

回调函数就是⼀一个通过函数指针调⽤用的函数。如果你把函数的指针(地址)作为参数传递给 另⼀一个函数,当这个指针被⽤用来调⽤用其所指向的函数时,我们就说这是回调函数。回调函数 不不是由该函数的实现⽅方直接调⽤用,⽽而是在特定的事件或条件发⽣生时由另外的一一⽅方调⽤用的,⽤用于对该事件或条件进⾏行行响应。

目前对函数指针的了解大概就这么多,如果学到新的内容会随时更新的。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/算法编织者/article/detail/63249
推荐阅读
相关标签
  

闽ICP备14008679号