第一点:我们们常常比较熟悉C语言中基本数学类型,比如,char,short,int,unsigned int ,float,double,struct studet{},union studet等。
C语言中的数组也是有自己的类型,比如int a[5],它的类型为 int [5],表示这个数组有5个元素,每个元素为int类型。因此我们就可以定义数组指针指向数组。
方法一:例如,现在要指向上述数组类型,则可以定义指针为 int (*p)[5],此时p就是一个数组指针,指向一个数组,这个数组大小为5,其中5个元素都为int类型。
方法二:我们可以利用typedef 关键字来定义数组类型,比如:typedef int(AINT5)[5];此时AINT5就是一个数组的类型,它有5个元素,每个元素的类型为int。注意,定义数组还有另外一种方式,typedef int AINT5 [5];就是在AINT5左右不加括号也可以,但是这种写法不太标准,我们一般采用的是 typedef int(AINT5)[5]这种写法。typedef是对一个已有的数据类型重命名,下面用一段代码解释大概了解它的用法:
#include <stdio.h>
typedef int(AINT5)[5];
int main()
{
AINT5 a;
int i=0;
int (*p)[5]=&a; //定义一个数组,指向这个数组
for(i=0;i<5;i++)
{
a[i]=i+1;
}
for(i=0;i<5;i++)
{
printf("%d\n",a[i]);
}
printf("\n");
for(i=0;i<5;i++)
{
printf("%d\n",(*p)[i]);
}
return 0;
}
同样的道理,C语言中函数也有自己的类型,函数的类型由函数的返回值,函数的参数个数,以及函数的参数类型共同决定。比如 int f1(int a,int b) 这个函数f1的类型就为,函数的返回值为int ,函数有2个参数,第一个参数为int类型,第二个参数也为int类型。同样的道理,既然函数有自己的类型,我们就可以定义指针指向这个函数,那么这个指针就是函数指针。
实例代码如下所示:
#include <stdio.h>
typedef int(*pi)(int);
int f1(int n)
{
return n*n;
}
void f2()
{
printf("call() f2()...\n");
}
int main(void)
{
pi p=f1;
void (*pv)()=f2; //这句话与下面这句话是一个意思
//void (*pv)()=&f2;
printf("&f1=%p\n",&f1);//函数名f1就是代表函数的入口地址,与&f1代表是一个意思
printf("f1=%p\n",f1);
printf("p=%p\n",p);
pv();//调用f2函数
(*pv)();//同样代表f2函数,这种写法也行
printf("f1(3)=%d\n",f1(3));
printf("p(3)=%d\n",p(3));
return 0;
}
有了上面的基础知识后,我们就可以分析下面的指针到底代表是什么意思呢??
int (*p1)(int*, int (*f)(int*));
// f是一个函数指针,这个指针指向一个函数,这个函数的类型为:int (int*),即返回值为int,有一个参数,参数的类型为int*。然后p1同样也是一个函数指针,指向的函数类型为 int (int*,f),即指向的函数类型的返回值为int,有2个参数,第一个参数类型为int*,第二个参数类型为f。
int (*p2[5])(int*);
//首先p2是一个数组,数组的大小为5,每个元素的类型为一个指针,这个指针为一个函数指针,指向的函数的类型为 int (int*),即返回值为int类型,有一个参数,参数的类型为int*。
int (*(*p3)[5])(int*);
//首先p3是一个指针,指向一个数组,这个数组大小为5,每个元素为一个指针,指向一个函数,函数的类型为 int (int*),即指向的函数类型的返回值为int类型,有一个参数,参数的类型为int*。
int*(*(*p4)(int*))(int*);
//首先p4是一个指针,它指向一个函数,函数的类型为 * (int*),即函数有一个参数,参数的类型为int*,函数的返回值为指针,指向另外一个函数,这个函数的类型为 int* (int*),即这个函数的返回值为int*,这个函数有一个参数,参数的类型为int*。
我们可以通过typedef 关键字来简化上述过程。
首先定义: typedf int* (*FuncType1)(int*)//
typedef (FuncType1*)(*FuncType2)(int*)//
FuncType2* p4 //这个就是最后P4的类型
int (*(*p5)(int*))[5];
//首先p5是一个指针,指向一个函数,这个函数的类型为 * (int*) 即,这个函数有一个参数,参数的类型为(int*),函数的返回值为一个指针,这个指针指向一个数组,数组的类型为int[5],即,数组的大小为5,里面每个元素为int类型。
当然我们可以通过typedef关键字来简化上述复杂的过程。就是上述分析过程的逆过程
首先定义一个数组,typedef int(ArrayType)[5]; //ArrayType代表的类型为 int[5]
typedef ArrayType* (*ArrayFunc)(int*) ;//ArrayFunc的类型为 ArrayType* (int*)
ArrayFunc* p5; //最后P5的类型就是一个函数指针