首先我们先了解一下数组和指针的基本概念。、
数组:顾名思义 ,是一类相同类型元素的集合,
指针:指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址.
#include <stdio.h>
int main()
{
int arr[5];//数组的创建 元素类型为 int 有5个元素。
int *p;//指针的创建,指向为 int 型的一个指针
return 0;
}
下来我们了解一下
1.指针数组
指针数组它是一个数组,里面存放的都是指针,所以称为指针数组
#include <stdio.h>
int main()
{
int *arr[10];//数组有十个元素,每个元素是一个指向int型的指针
char *arr2[10];//数组有十个元素,每个元素是一个指向char型的指针
short *arr[10];//数组有十个元素,每个元素是一个指向short型的指针
return 0;
}
2.数组指针
上面说了指针数组是数组那么数组指针是什么呢?答案是他是一个指针,因为这个指针有能力指向一个数组,所以我们称他为数组指针。
#include <stdio.h>
int main()
{
int (*p)[10];//p是一个指针指向一个数组,数组里面有10个元素,每个元素的类型是int 型。
//数组指针,和指针数组相比就差了一个小括号,也就是因为这个小括号,调整了优先级的关系
//导致*先与p结合形成了一个指针然后再和后面的[]结合形成了一个数组指针
return 0;
}
那么在什么情况下我们会用到我们的数组指针呢,下来我来举个例子
#include <stdio.h>
int main()
{
int arr[10] = {0};
//arr:表示数组首元素的地址
//&arr:表示数组的地址
printf("%p\n",arr);
printf("%p\n",arr+1);//跳过一个元素
printf("%p\n",&arr+1);//越过一个数组
//当程序运行之后我们会发现结果不同,因为虽然 &arr 和 arr 的值相同但意义却不同。
//说明数组也有地址 这时候就需要一个可以存放数组地址的工具。就是我们的数组指针
int (*p)[10]; //数组指针
return 0;
}
相信通过上面的分析大家对数组指针和指针数组也有了一定的概念和区分能力。
3.函数指针、
函数指针,一看名称就能看出来是一个指针,他指向的是函数所以称为函数指针,这时候有人会有疑问,函数也有地址吗答案是有。
#include <stdio.h>
void test()
{
printf("hello\n");
}
int main()
{
printf("%p\n",test);
printf("%p\n",&test);
return 0;
}
通过程序运行我们可以看到会输出两个相同的地址。
既然出现了地址,那我们如何保存呢,这时候就能体现函数指针的作用了。
int main()
{
void (*p)();//这是一个指针指向的是一个函数,指向的函数并没有参数,也无返回值。
//这就是函数指针 注意必须要加小括号保证优先级顺序的正确,
return 0;
}
4.接下来就是函数和指针还有数组的结合 函数指针数组
他就是一个数组,不过里面存放的指针是指向函数的指针。下来我们看看函数指针数组的定义
#include <stdio.h>
int main()
{
int (*p[10])(); //p先与[]结合说明他是一个数组然后与*结合说明里面存放的指针在与()
//结合说明指针指向的是一个函数
return 0;
}
5.函数指针的数组的指针
这个名字一听就很复杂,但是当我们一步步来分析这个东西其实发现并不麻烦,
首先他是一个指针,指向一个数组,然而这个数组的元素都是指向函数的函数指针。
那么函数指针的数组的指针又该如何定义呢?
#include <stdio.h>
void test(const char *str)
{
printf("%s\n",str);
}
int main()
{
void (*p)(const char*) = test; //这是一个函数指针
void(*parr[5])(const char*); //这是一个数组存放函数指针的数组
parr[0] = test;
void (*(*pparr)[10])(const char*) = &parr; //这就是一个指向函指针数组的指针
return 0;
}
大家对这些概念都能理解了吗?