在介绍指针定义之前,首先声明一些概念:
指针和数组无关:1.指针和数组是两种不同的类型。2.数组名不能整体赋值,数组名不能作为左值。
数组名单独使用时代表整个数组,数组名在被取地址时,代表整个数组的地址。
下来,我来介绍一些常见的指针名词:
指针数组:是数组,是一个存放指针的数组。比如:int *arr[10].
数组指针:是指针,有能力指向一个数组。比如:int (*p)[10];//注意:[]的优先级要高于*号,所以必须加上()来保证p先和*结合。
函数指针:是指针,有能力指向一个函数,既可以通过指针调用函数,亦可通过函数名直接表示。比如:int (*a)(int x,int y)。
函数指针数组:是数组,这个数组中的元素就是我们前面所提到的函数指针。比如:int (*parr1[10])()。
指向函数指针的数组的指针:是指针,指针指向一个数组,数组的元素都是函数指针。比如:void(*(*ppfunarr)[10](const char*).
看完了文字介绍之后,我们来通过代码对此分析:
#include <stdio.h>
#include <stdlib.h>
#include<windows.h>
char *fun(char *p1, char *p2)
{
int i = 0;
i = strcmp(p1, p2);
if (0 == i)
{
return p1;
}
else
{
return p2;
}
}
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()
{
int *arr[5];//指针数组
int (*pArr)[5] = &arr;
//数组指针,
//它是一个指针,指针有能力指向一个数组
//数组有5个元素,每个元素是一个整形指针
char *(*pf)(char *p1, char *p2);
pf = &fun;
(*pf)("aa", "bb");
//pf是一个函数指针;
//该指针指向一个函数;
//指向的函数参数为char*,char*类型,返回值类型为char *;
char *(*a[3])(char *p);
//a是一个函数指针数组;
//该数组有三个元素,为函数指针;
//该指针指向函数,函数参数为char *类型,返回值为char*;
char *(*(*pe)[3])(char *p);
//指向函数指针数组的指针;
//是指针,指向函数指针数组;
//该数组有三个元素,为函数指针;
//该指针指向函数,函数参数为char *类型,返回值为char*;
pe = &a;
a[0] = fun1;
a[1] = &fun2;
a[2] = &fun3;
pe[0][0]("fun1");
pe[0][1]("fun2");
pe[0][2]("fun3");
system("pause");
return 0;
}
通过以上学习,我们对概念都有了一些了解,接下我们通过两个代码对自己做一点小测试吧:
void(*signal(int, void(*)(int)))(int);
//是一个函数声明,signal是一个函数,
//参数为int类型和函数指针类型,返回值为函数指针类型
代码也可简化如下:
typedef void(*pfun_t)(int);
pfun_t signal(int, pfun_t);
是不是感觉上个例子不够刺激,接下来我们再来看个例子吧:
(*(void(*)())0)()
//void(*)(),这是一个函数指针类型,这个函数没有参数,没有返回值
//(void(*)()0),这是将0强制转换为函数指针类型,0是一个地址,也就是说一个函数存在首地址为0一段区域内。
//(*(void(*)()0),这是取0地址开始的一段内存里面的内容,其内容就是保存在首地址为0的一段区域内的函数。
//(*(void(*)())0)(),这是函数调用。
通过以上分享,希望能帮到大家!
对于函数指针,后面还有一些深度理解:https://blog.csdn.net/cdatreides/article/details/80427054