先分清两个概念:数组指针、指针数组。
指针数组
指针数组就是一个存放指针的数组。
数组指针
数组指针就是一个指针,这个指针指向数组的地址。
//下面分别是数组指针和指针数组的定义。
int (*p)[];//数组指针
int *arr[];//指针数组
这里判断的话主要看优先级,前者的话*先于p结合,所以是一个指针变量。因为[]的优先级高于*,后者是指针数组。
注意:指针加减,加减的是所指向数据类型的大小
举个例子:
int arr[10];
printf("%p\n", arr);//首元素的地址
printf("%p\n", &arr);//整个数组的地址(与首元素地址相同、但意义不同)
printf("%p\n",&arr+1);//加的是整个数组的大小
printf("%p\n",arr+1);//加的是int类型元素的大小
注意:
只有在sizeof(arr)、&arr,数组名才代表整个数组,其余都表示首元素的地址。
数组传参
1.数组传参,要降级。降为指向其内部元素类型的指针。
2.可以把所有数组都看作一维数组。例如,二维数组,可以把它看作内部元素为一维数组的数组。
一维数组传参
int arr[3];
void fun(int *arr);
void fun(int arr[]);
void fun(int arr[3]);
二维数组传参
int arr[3][5];
void fun(int arr[3][5]);
void fun(int arr[][5]);
//不能[]内容全部省略,只能省略第一个[]。必须知道指针所指向的元素类型
是什么
void fun(int (*arr)[5]);
//二维数组看作一维数组的话,内部元素是含有五个元素的一维数组
函数指针
函数指针:void *fun();
要与 int *fun[];
int (*p)[];区分
函数指针数组
定义
int (*p[10])();
函数指针调用时可以直接调用,也可解引用调用。
int fun(int x, int y);
int (*p)(int,int)=fun;
int ret;
ret = (*p)(1,2);//1
ret = fun(1,2);//2
ret = p(1,2);//2
三种调用方式都是可行的。
函数void fun(int x, int y); fun与&fun都代表函数的地址
函数指针数组的用途
转移表
举个例子:
计算器的+-/之前我们可能都会用switch语句来实现。在学习了函数指针数组之后,我们就可以把实现+-/的函数地址存放到一个函数指针数组中。再用函数指针调用。
int add(int x, int y);
int sub(int x, int y);
int mul(int x ,int y);
int div(int x, int y);
//+-*/函数(这里就不写函数定义了)
int (*p[5])(int x ,int y)={0,add,sub,mul,div};
int ret = (*p[1])(1,2)//实现两数相加