函数指针数组,函数指针数组指针
1、首先明确两点:函数指针数组本质上是一个数组,函数指针数组指针本质上是一个指针。
2、函数指针数组
函数指针数组本质上是一个数组:
前面的一大串都可以看作是一个形容词,重点在最后的“数组”,函数指针数组其实本质上就是一个数组,函数指针作为形容词,由此得出这个数组是函数指针类型,也就是数组里的每个元素都是函数指针类型。概念清楚之后我们来看看实际形式:
typedef int (*Pfun[])(int, int);
这里们定义了一个函数指针类型Pfun,这个函数返回值为int类型,形参列表是两个int类型。由于“ [ ] ”运算符优先级高于“ * ”,Pfun首先和“ [ ] ”结合,这就决定了Pfun实质上是一个数组,然后和“ * ”结合,由此得出Pfun不仅是一个数组,还是一个指针数组,表明这个数组里的每个元素都是一个指针类型。再往外一层与函数结合,可以看出,数组里的元素不仅是一个指针类型,还是一个函数指针类型。
有了自定义类型,我们就可以定义变量并使用:
首先定义几个函数,实现简单的加减乘除功能:
int Add(int a, int b) //加
{
return a + b;
}
int Sub(int a, int b) //减
{
return a - b;
}
int Mul(int a, int b) //乘
{
return a*b;
}
int Div(int a, int b) //除
{
return a / b;
}
定义一个函数指针数组变量并初始化:
Pfun pfun = {Add, Sub, Mul, Div};
使用数组方式访问函数指针:
int main(void)
{
Pfun pfun = {Add, Sub, Mul, Div};
int i, result;
for(i = 0; i < 4; i++)
{
result = pfun[i](4, 2);
printf("result = %d\n", result);
}
return 0;
}
当然也可以按指针方式访问数组中的元素:
int main(void)
{
Pfun pfun = {Add, Sub, Mul, Div};
int i, result;
for(i = 0; i < 4; i++)
{
result = (*(pfun+i))(4, 2);
printf("result = %d\n", result);
}
return 0;
}
Linux下GCC编译运行结果如下:
3、函数指针数组指针
函数指针数组指针本质上是一个指针:
有了上面的分析,我们大概懂得了怎么理解类似概念,重点放在最后一个词上面。首先明确这是一个指针类型,是怎样一个指针类型呢?就是我们上面所说的函数指针数组的指针,这个指针指向一个函数指针数组,本质上就是一个数组的首元素的地址,同时在数值上也等于数组首元素的首地址,在32位机上,这个指针就占4个字节。概念清楚后看形式:
typedef int (*(*Ptype)[])(int, int);
首先,Ptype与“ * ”结合明确Ptype是一个指针类型,接着与“ [ ] ”结合表明这是一个数组指针,再与外面的函数指针结合表明这个数组内的元素是函数指针类型。
我们定义了一个函数指针数组指针类型Ptype,指向上文所说的的函数指针数组,然后我们定义一个Ptype类型的变量ptype,将pfun的地址赋值给ptype。
Ptype ptype = &pfun;
注意这里一定要加“ & ”取地址符,不然会报如下的warning:
因为我们定义的是一个函数指针数组指针类型,需要给这个变量赋值必须是一个函数指针数组的地址,而pfun是数组名,仅仅代表数组首元素的地址,如果直接用数组名赋值,就会出现类型不匹配的问题。
可以通过以下方式访问数组中的元素:
int main(void)
{
Pfun pfun = {Add, Sub, Mul, Div};
Ptype ptype = &pfun;
int i, result;
for(i = 0; i < 4; i++)
{
result = ((*ptype)[i])(4, 2); //函数指针数组指针方式访问元素
printf("result = %d\n", result);
}
return 0;
}
运行结果和上面的一样。
4、总结:
本文通过一定的实例介绍了函数指针数组以及函数指针数组指针,先通过概念理解两者之间的区别,在遇到实际问题时,注意变量本质上是一个什么样的类型,从本质入手,也就很容易理解了。
新人才疏学浅,有错的地方敬请指正!!