指针数组 数组指针 函数指针 函数指针数组 指向函数指针数组的指针 的理解与解释

指针数组

顾名思义,是一个数组,类似于整型数组是由整型组成的数组,那么指针数组就是由指针组成的数组。书写格式如下:

int*p[10]; 
char*p[10];

因为[ ] 的优先级比 * 高,所以变量p先与 [ ] 结合表示他是一个数组,数组大小为10。然后再与 int* 结合表示数组里面存储的是整型指针,当然 char* 存储的就是字符指针。
类似于整型数组指针

int a;  //这是一个整型变量
int a[10];   //变量a先与[]结合 这是一个数组  存储整型
int* p;   //这是一个整型指针变量
int* p[10];   // 变量p先与 [] 结合  再与int*结合  这是一个数组 存储整型指针

数组指针

显然这是一个指针,先来看一下它的书写格式:

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

由于加了 ( ) ,优先级发生改变,变量p先与 * 结合,代表它是一个指针,再与int[10]结合,说明它指向一个存有十个整形的数组的地址。类似于:

int* p;  //p*结合,代表它是指针,指向存有int整型的地址
int(*p)[10]; 

函数指针

函数指针也是一个指针,它指向一个函数的地址。首先我们定义一个函数,再让一个指针指向它:

void test1()
{
    printf("hello\n");
}

int test2(int x,int y);
{
    return x+y;
}

int main()
{
    void(*p1)() = &test1;  //函数指针的定义与赋值
    int(*p2)(int,int) = test2;
}

可以看到函数指针和函数数组类似,()的优先于高,变量先与 * 结合表示它是一个指针,再将对应的函数返回值和参数类型添加进去,就组成了函数指针。

在使用函数指针的时候,以上面为例没有参数的可以直接test1()进行调用,有参数的test2(5,6)进行调用,注意参数的类型必须一致。

可以假设一下不带括号:

int* p();

这相当于一个返回int*型函数的声明。

&test1和test2都可以得到一个函数的地址,可以用

printf("%p\n",test);
printf("%p\n",&test);

进行验证,得到的是两个相同的地址。

函数指针数组

这是一个数组,它存放的是函数指针。我们先来看一下他的书写格式:

void(*p1[5])();
int(*p2[10])(int,int);

我们逐个分析,变量p1先与 [] 结合,表示它是一个数组,然后这个数组里面存储的是 void(*)() 这样类型的函数指针,无返回值无参数。类似于:

int *p1;    //这是一个整型指针
int *p1[5];  //刚才上面讲过,这是个数组,里面存储的是int* 类型的指针
void(*p2)();  //这是一个函数指针
void(*p2[5])();  //可以参考p1,它俩都在变量名后面加了[5],改变为数组,存储没加[5]之前代表的类型

函数指针数组在解决需要调用大量相同函数返回值和相同参数个数、类型的时候,有非常重要的作用。

指向函数指针数组的指针

为了加深理解,我们来学习这个指针,我感觉一般不会用到。
这是一个指针,书写格式如下:

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

首先括号的优先级高,我们先看最里面的括号,p先与 * 结合表示他是一个指针,从括号里面出来,与 [5] 结合,表示它指向一个数组,剩下 void(*)(),表示数组里面保存的是返回值为void没有参数的函数指针。类似于:

int p1[5];   //这是一个整型数组
int (*p1)[5];  // p先与*结合,表示他是一个指针,括号出来与[]结合,表示他指向一个数组,剩下一个 int 表示这个数组里面存储的是整型
int(*p2[10])(int,int); //上面讲过,这是一个函数指针数组
int(*(*p2)[10])(int,int); //类似于p1的解释。

总结

指针和数组,只要搞清楚优先级,从高到低,一步一步从括号走出来,逻辑不能乱。

猜你喜欢

转载自blog.csdn.net/qq_39487033/article/details/80256148