函数指针 、函数指针数组 、函数指针数组的指针

在指针的学习过程中有这么几种指针在定义是经常会让我们犯错:函数指针、函数指针数组、函数指针数组的指针。下面我们逐个了解这几种指针。

一、 函数指针

函数指针顾名思义:指向函数的指针
我们知道整型、浮点型、字符型指针存放的都是其对应变量的存储地址,那么很容易可以理解,函数指针存放的就是函数的地址。
函数的地址是什么呢? 我们看下面的代码:

void test()
{
	printf("hello world\n");
}
int main()
{
	printf("%p\n",&test);
	printf("%p\n",test);
	return 0;
}

在这里插入图片描述
可以看出函数名和函数的地址是一样的。那么函数的地址要保存起来势必需要一个指向该函数的指针,也就是我们说的函数指针。
那么问题来了,函数指针怎么定义呢?
看下面的代码:

void test()
 {
     printf("hehe\n");
 }
  //下面pfun1和pfun2哪个有能力存放test函数的地址?
   void (*pfun1)();
    void *pfun2();

首先,能给存储地址,就要求pfun1或者pfun2是指针,那哪个是指针?

答案是:
pfun1先和*结合,说明pfun1是指针,指针指向的是一个函数,指向的函数无参数,返回值类型为void。pfun2是在函数指针定义过程中最常见的错误定义的方式。
看下面两段有趣的代码:

//代码1 
(*(void (*)())0)(); 	//这是一个函数调用,将0强转成函数指针,对其解引用得到0地址处的函数。这个函数无参数和返回值类型。

//代码2 void (*signal(int , void(*)(int)))(int); 	  //这是一个函数的声明。该函数的返回值为void (*) (int)  ,函数名是signal ,参数有两个,一个是 int,一个是 void (*) (int).


代码2可以化简如下:
typedef  void (*func) (int)
func signal(int ,func);

二、函数指针数组

数组是一个存放相同类型数据的存储空间,那我们已经学习了指针数组, 比如:

int* a[10];	//定义一个指针数组 每个元素是int* 

那要把函数的地址存到一个数组中,那这个数组就叫函数指针数组,那函数指针的数组如何定义呢?

1.既然是指针 那么变量名必定应该与 [] 先结合构成一个数组 如 :arr[]。
2.这是一个 “函数指针” 数组,整型数组每个元素的类型是整型,那么函数指针数组每个元素的类型就是“函数指针”即 数据类型 + (*) (参数列表)
然后我们看下面的代码:

int (*parr1[10]])(); 
int *parr2[10](); 
int (*)() parr3[10];

上面几种定义的方法那个是正确的?
答案是:parr1 parr1 先和 [] 结合,说明parr1是数组,数组的内容是什么呢? 是 int (*)() 类型的函数指针。

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

指向函数指针数组的指针是一个 :“指针” 指针指向一个 数组 ,数组的元素都是 函数指针 。
如何定义?

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;
         }

以上就是三种函数的正确理解与定义。

发布了70 篇原创文章 · 获赞 12 · 访问量 9802

猜你喜欢

转载自blog.csdn.net/lovehang99/article/details/100526037