C语言:深度理解 指针数组, 数组指针 ,函数指针, 函数指针数组 ,指向函数指针数组的指针

指针数组

int *p[10](指针数组是数组,是存放指针的数组)
具体来说:因为[ ]的优先级高,所以[ ]先与p结合成为一个数组,然后这个数组的类型为int*,也就是整形指针,该数组含有10个指针类型的数组元素。这里执行p+1时,则p指向下一个数组元素。

数组指针

int (*p)[10](是指向一个数组的指针)

具体来说:因为()的优先级高,p和*结合,说明p是一个指针,该指针指向了int型的一维数组,这个一维数组的长度是10,也就是p的步长。当执行p+1时,p会跨过10个整型数据的长度。

eg1:

下面通过一个例子简单说明数组指针和指针数组

int  (*p[10])[5] ;

表示什么意思?

这句话是说:p是一个数组,数组有10个元素,每个元素是一个数组指针,该指针能够指向大小为5的,每个元素为整形的数组。

函数指针

void(*p)(char* str)=test;

具体来说:因为因为()的优先级高,p和*结合,说明p是一个指针,这个指针指向了一个函数,而且指向的函数参数为char*类型,返回类型为void,指针p存的是test的地址。

int(*p)(int, int);          //就是一个函数指针

函数指针数组

把函数的地址存到一个数组中,这个数组就被称为函数指针数组

int(*p[4])(int, int);      //函数指针数组

指向函数指针数组的指针

指向函数指针数组的指针首先是一个 指针 ,该指针指向一个数组 ,数组的每个元素都是 函数指针

int(*(*p)[4])(int, int);    //指向函数指针的数组的指针

eg2:

(*(void(*)())0)();

怎么理解这句代码?

分析:我们希望0是某个函数的地址,所以把它强制类型转换为函数的指针类型,这个时候它就是个函数地址了,在前面加个*,表示解引用操作,找到这个函数,后面去调用它,调用的时候,因为函数无参,所以不用传参数。这是分析过程,那么具体如何描述呢?

答:调用0地址处的函数,调用的函数的参数是无参,返回类型为void,还要解释的话,可以这样说:把0强制类型转换为函数的指针类型,解引用,去找到这个函数,并调用该函数,调的函数没有参数,返回类型为void。

eg3:

typedef void(*pfun_t)(int);
pfun_t signal(int, pfun_t);

怎么理解这句代码呢?

分析:分析这种复杂的代码,首先,我们得找到一个名字或者一个符号开始,这个代码呢,就从signal开始,这是函数,而且是函数声明,不是函数调用,为什么这样说呢?调用函数有传参,但是这里面没传参,有的人可能会说传的是int,但是传int时,也只能传1,2,3,或者其他整形数字,不可能会传int过去,所以这绝对不是一个函数的调用,而是一个函数的声明,它的参数为int和函数指针,返回类型为函数指针。

这段代码可以写成:

void (*signal(int,void(*)(int)))(int);

  void (*signal(int,void(*)(int)))(int),signal(int,void(*)(int))就是函数名和函数参数,去掉signal(int,void(*)(int))之后,剩下的就是函数的返回类型void (*)(int),所以它返回的是一个函数指针,该指针指向函数的参数是int,返回类型为void。

不过,我们理解的的写法应该是:

void(*)(int) signal(int,void(*)(int));

但是实际上并不这样写。这个代码太复杂,我们写的代码应该是让别人读得懂的,所以可以使用 typedef 把它简化一下:

typedef void(*ptr_t)(int);
ptr_t signal(int,ptr_t);

分析了这么多,这段代码具体应该这样解释:

signal是一个函数声明,函数的参数为int和一个函数指针,该函数指针指向的函数参数为int,返回类型为void;signal函数的返回类型也为函数指针,该函数指针指向的函数参数为int,返回类型为void。

猜你喜欢

转载自blog.csdn.net/qq_42270373/article/details/81291097