开门见山,本篇的主要内容是:指针数组,数组指针,函数指针,函数指针数组,函数指针数组指针。
看见题目是不是有点晕晕的感觉,没关系等看完这篇博客你会觉得他们其实也很好理解的!
接下来我一个一个介绍。
一.指针数组
顾名思义,指针数组就是一个数组里面存放的内容是指针
如:int *p1[10]
解析1.首先写出一个数组:p1[10],这是一个大小为10的数组
2.其次写出数组里面存储的内容为int *即为整型指针类型,便得到int *p1[10]
用如下示意图深入理解:
二.数组指针
指向数组的指针,也很好理解
如: int (*p2)[10]
解析:1.因为是指针,所以首先写出一个一个指针(*p2),因为[]的优先级比*高如果不加()就会变成指针数组
2.指针已经写好了,接下来让它指向一个数组就好了,(*p2)[10],指向一个大小为10的数组
3.写出指向的数组类型int (*p2)[10],指向的数组类型为int,这就得到了数组指针。
记住:这里的p2是指针变量,它可以指向一个数组,注意和指针数组中的p1区分,p1是数组名。
用图示深入理解:
使用举例:
int main()
{
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int(*p2)[10] =&arr;
printf("%d", **p2);//输出1
system("pause");
return 0;
}
三.函数指针
指向函数的指针,可以参考数组指针去理解。
如:char *(*fun)(char *p1,char *p2)
解析:1.因为是函数指针嘛,首先写出一个指针(*fun)
2.在这个指针后面紧跟着一个(),里面是他所指向函数的形参类型,便得到(*fun)(char *p1,cahr *p2),这个函数的两个形参都是char *类型的
3.指针变量的前面是所指向的函数的返回类型,char *(*fun)(char *p1,char *p2)这里的返回类型是char *
注意所指向的函数如果没有返回类型和参数的话这样写,如void(*fun)(void)
使用举例:
#include<stdio.h>
#include<string.h>
char *fun(char *p1, char *p2)
{
int i = 0;
i = strcmp(p1, p2);
if (i == 0)
{
return p1;
}
else
{
return p2;
}
}
int main()
{
char *(*p)(char *p1, char *p2);//定义了一个函数指针
p = &fun;//将函数的地址存放在指针变量里面
printf("%s",(*p)("aa", "bb"));//通过函数指针调用函数
system("pause");
return 0;
}
举一个有点意思的函数指针:(*(void(*)())0)()
这个例子看着复杂其实一点也不复杂
分析:1.void(*)()这是一个函数指针,指向的函数没有返回类型没有参数
2.(void(*)())0这里是 将0强制类型转换为函数指针类型,0是一个地址,也就是说一个函数存在一个首地址为0的空间里面
3.(*(void(*)())0) 对0进行解引用,取0地址里面存的内容,其实就是取0地址里面所保存的函数
4..(void(*)())0() 最后这个是对函数的调用
现在是不是觉得这个表达式很好理解了
四。函数指针数组
根据名字去理解,就是一个数组,里面存放的内容是指向函数的指针
所以这块内容主要是数组
如:cahr *(*pf[3])(char p)
分析:1.既然是数组那么就先写一个数组pf[3],da
2.我们已经知道了数组里面的类型是指针类型,所以得*pf[3],表示大小为3的数组里面的元素类型为*
3.接下来就和函数指针的写法有点类似,数组里面的函数指针所指向的函数的参数和返回类型 char *(*pf[3])(char *p)
由表达式可知函数的返回类型为char *,参数为char *
使用举例:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char *fun1(char *p)
{
printf("%s\n", p);
return p;
}
char *fun2(char *p)
{
printf("%s\n", p);
return p;
}
char *fun3(char *p)
{
printf("%s\n", p);
return p;
}
int main()
{
char *(*pf[3])(char *p);//定义了函数指针数组,里面的内容是函数指针
pf[0] = &fun1;//将函数的地址赋值给函数指针数组中的函数指针
pf[1] = &fun2;
pf[2] = &fun3;
pf[0]("fun1");//调用函数
pf[1]("fun2");
pf[2]("fun3");
system("pause");
return 0;
}
五。函数指针数组指针
这个听名字是不是觉得有点绕,如果你把前面的那些理解了的话这个也是很好理解的函数指针数组指针,就是一个指针,指向一个数组,这个数组的元素内容是函数指针。
如:char *(*(*pf)[3])(cahr *p)
分析:
1.因为是指针类型,所以首先写出一个指针*pf
2.这个指针指向一个数组数组里面的元素类型又是指针,所以得*(*pf)[3]
3.接下来就和函数指针数组的写法一样了只需要写上数组里面的函数指针指向的函数的返回类型和参数就好了就有结果char *(*(*pf)[3])(cahr *p)c参数和返回类型都输cahr *
使用举例:
#include<stdio.h>
#include<stdlib.h>
char *fun1(char *p)
{
printf("%s\n", p);
return p;
}
char *fun2(char *p)
{
printf("%s\n", p);
return p;
}
char *fun3(char *p)
{
printf("%s\n", p);
return p;
}
int main()
{
char *(*a[3])(char *p);//定义函数指针数组
char *(*(*pf)[3])(char *p);//定义函数指针数组指针
pf = &a;//将数组的地址赋值给函数指针数组的指针变量
a[0] = &fun1;//将函数的地址赋值给函数指针变量
a[1] = &fun2;
a[2] = &fun3;
pf[0][0]("fun1");//通过函数指针数组指针访问函数进而调用函数
pf[0][0]("fun2");
pf[0][0]("fun3");
system("pause");
return 0;
}
通过上面分析大家一定对这块的概念不在觉得那么难理了吧,但是你想要运用自如,还需要大量的练习
如果发现上述内容有什么错误欢迎私信我,大家一起学习进步,谢谢!