1.指针数组
什么是指针数组呢?
比如:
int *arr[10];
int *a[4];
int **arr[10];
以上这些都是指针数组,为什么 呢?首先 拿第一个为例,arr先与[10]结合成为一个数组,然后这个数组里存着10个元素,每个元素的类型为int*;第二个也一样。第三个的意思是arr与[10]结合成为一个数组,数组的元素类型为int**。总的来说就是存放指针的数组叫指针数组。它怎么用呢?如下:
int *arr[10] = {"hello","werer"};
这里面因为存放的都是一个int型的指针,所以每个指针都可以指向一个字符串。
2.数组指针
那么数组指针又是什么呢?
比如:
int (*p)[10];
这种类型的叫做数组指针,首先*与p结合,形成一个指针,然后指向一个有10元素的数组。概括来说就是p是一个指向数组的指针,所以叫做数组指针。那它有什么作用呢?如下:
int arr[] = {1,23,4,5};
int (*p)arr = &arr;
void A(int (*p)[5])
{
}
int main()
{
int a[3][5];
A(a);
return 0
}
首先如我们看到的一样,他可以存放一个数组的地址,其次第二个就是它可以接受一个二维数组的传参。因为二维数组的数组名是第一行的地址,所以数组指针就是用一个指针来指向第一行,再用数组指针的下标来找到一行的每个元素,指针加一就可以指向下一行。
警告:
int arr[5];
int *pa[10];
int (*ppa)[10];
如果出现下面的情况你认为可以吗?
int (*ppa)[10] = &pa;
int (*ppa)[10] = &arr;
这样是不可以的,第一行数组内的每个元素是int型,而pa内的每个元素是int*,所以不可以这样做。
第二行的arr数组虽然每个元素是int型,但是这个数组内只有5个元素,而ppa这个数组指针指向的是一个有10个类型的数组,所以类型不匹配,也不可以。
3.存放数组指针的数组
首先它是数组,里面存放的都是数组指针,那么在数组指针的基础上就可以写成这样
int (*pppa[4])[10];
这就是一个数组指针的数组。
4.函数指针
其实函数也有地址,函数名就是它的首地址,这就和一维数组的数组名一样。让我们先看一段代码。
#include<stdio.h>
#include<stdlib.h>
void Asd()
{
printf("hehe");
}
int main()
{
printf("%p\n", Asd);
printf("%p\n",&Asd);
system("pause");
return 0;
}
这样就可以看出,函数名就是函数的首地址了吧。函数名和取地址函数名是一样的,这点与数组不相同。
void (*p)() = Asd;
上面这个就是一个给函数指针赋值的过程,*p要加括号,不然p就会先与()结合之后再与*结合,这样p就不是一个指针了。
()里放的是实参的类型,因为这个函数没有传参所以不放任何东西。
5.函数指针数组
数组是存放相同类型的存储空间,如果将函数指针放入数组里就是函数指针数组,既然是数组就要先与[]结合,所以数组指针如下
void (*p[3])();
这里面可以存放三个函数指针,这就是函数指针数组。
用下面一段代码来熟悉一下函数指针数组:
#include<stdio.h>
#include<stdlib.h>
void menu()
{
printf("**********************\n");
printf("***1.Add 2.Sub ****\n");
printf("***3.Mul 4.Div ****\n");
printf("*** 0. exit ****\n");
printf("**********************\n");
}
int Add(int x, int y)
{
return x+y;
}
int Sub(int x, int y)
{
return x-y;
}
int Mul(int x, int y)
{
return x*y;
}
int Div(int x, int y)
{
return x/y;
}
int main()
{
int i = 0;
int j = 0;
int input = 0;
int ret = 0;
int (*put[5])(int, int) = {0, Add, Sub, Mul, Div};
do
{
menu();
printf("请选择:");
scanf("%d", &input);
if(input>=1&&input<=4)
{
printf("请输入两个参数:");
scanf("%d%d", &i, &j);
ret = (*put[input])(i, j);
printf("ret = %d\n", ret);
}
else if(input<0||input>4)
{
printf("输入错误\n");
}
else
{
printf("退出游戏\n");
}
}while(input);
system("pause");
return 0;
}
这是一个实现计算器功能的函数,其中因为加减乘除函数的类型相同,所以可以将它们四个数组的地址用函数指针数组来存放。这里面的(*put[5])(int , int )就是一个函数指针数组。这样你对函数指针是数组有了一定的了解了吧。
6.函数指针数组的指针
既然了解了上面的函数指针数组,我们就再深入了解函数指针数组的指针。听起来有点绕口,但是我们慢慢分析就可以了,
首先他是一个指针,所以他必须与*先结合,他指向的是一个存放函数指针的数组,所以就可以写成这样:
void (*(*p)[3])();
也就是在函数指针数组的基础上将p在变成一个指针。它有什么作用呢?
它可以存放函数指针数组的地址。让我们在用一段代码了解一下:
#include<stdio.h>
#include<stdlib.h>
void Asd()
{
printf("hehe");
}
int main()
{
void (*p)() = Asd;//用一个函数指针来指向这个函数
void (*q[3])() ;//函数指针数组
q[0] = p;//用一个函数指针数组来存放这个函数指针
void (*(*a)[3])() = &q;//用一个函数指针数组的指针指向这个函数指针数组
system("pause");
return 0;
}