指针数组,数组指针,函数指针,函数指针数组与指向函数指针数组的指针

首先,指针是什么?

指针(Pointer)是编程语言中的一个对象,利用地址,它的值可以直接指向存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化地成为“指针”。即指针是一个用来存放地址的变量。

而数组和函数不用多说:数组是一组相同类型元素的集合;函数是在大型程序中完成某项特定任务的部分代码,具有相对的独立性,也可以理解成是一个子程序。

那么,指针数组,数组指针,函数指针,函数指针数组与指向函数指针数组的指针又是什么?分别有怎样的定义和特点呢?

指针数组:

指针数组是一个数组,是一个用来存放指针的数组。

例如:char  *arr[3]={"abc","opq","xyz"};

这是一个 char 类型的数组,里面存放的是三个指针,而这三个指针又分别指向的是字符串:“abc”,“opq”和“xyz”。

数组指针:

顾名思义,数组指针是一个指针,是一个指向某个数组的指针。

例如:int(*p)[10];

在这里,p先和*结合,说明p是一个指针变量,它指向一个包含10个元素的整型数组。(由于[]的优先级高于*,所以在这里必须加上()来保证p先于*结合)。

函数指针:

函数指针是一个指向函数地址的指针。函数指针的使用需要在代码中先写一个函数,然后定义一个指针来保存它的地址。

例如;

#include<stdio.h>
void test()
{
	printf("hello world\n");
}
int main()
{
	test();
	printf("%p\n",test);     //输出test函数的地址
	system("pause");
	return 0;
}

这里的第一行输出的是该函数的结果,第二行输出的是该函数的地址:


如果想将这个地址保存起来,就需要使用函数指针: void  (*p)()=&test;    //表示指针p指向test函数的地址。

这个例子不太明显,换一个比较经典的例子;

void   (  singal    (  int , void  (  *  )  (  int  )  )  )(  int  );

对这行代码进行一层层的解读:

·首先,singal是一个函数的声明;

·singal有两个参数,一个是int,另一个是函数指针:void  (  *  )  (  int  );  

·该函数指针void  (  *  )  (  int  )  指向的函数有一个int 参数,返回类型为 void singal函数的返回类型为一个函数指针;

·该函数指针指向的函数有一个Int参数,返回类型为void;

将这行代码进行如下简化可以更清楚一些;

typedef   void  (   *pfun_t  ) (  int  );     //typedef为重命名关键字,*pfun_t为新的类型名。

pfun_t   singal  (  int  ,  pfun_t  );

函数指针数组:

上面说到了指针数组与函数指针,现在看函数指针数组:

函数指针数组同样是一个数组。它里面存放的是函数指针;

这里有一个指针数组,该数组中的每个元素是int*;

int *arr[10];

如果要把函数的地址存放到该数组中,南无这个数组就叫函数指针数组,定义如下:

int (*arr[10])();       //arr先于[]结合,说明arr是一个数组,而它的内容是 int (*)()类型的函数指针

函数指针数组的用途之一是用作转移表,将在后面的博客中与大家分享。

指向函数指针数组的指针:

指向函数指针数组的指针是一个指针,它指向的是一个数组,而该数组的元素都是函数指针;

看一下它们代码的不同之处;

   1.     void(*p)(const char) = test);                        //这是一个函数指针p,参数类型为const char,返回类型为void
   2.     void(*parr[5])(const char *str);                     //这是一个函数指针的数组parr,可以存储5个函数指针
   3. 	void(*(*pparr)[10])(const char*) = &pfunarr;           //这是指向函数指针数组parr的指针pparr

即代码2中的数组可以存储代码1的指针,而代码3的指针又指向代码2中的数组。










猜你喜欢

转载自blog.csdn.net/n_peng/article/details/80414303
今日推荐