指针数组
指针数组是数组,是一个存放指针的数组。
eg:
int *arr1[10];//整形指针数组,有十个元素,每个元素都是整形指针。
char *arr2[4];//字符指针数组,有四个元素,每个元素都是字符指针。
char **arr3[5];//数组有5个元素,每个元素是字符型的二级指针。
数组指针
数组指针是指针,是一个指向数组的指针。
eg:
int *p[10]; //整形指针数组
int (*p)[10]; //数组指针
// 解释: p 先和 * 结合,说明 p 是⼀个指针变量,然后指向的是⼀个⼤小
//为10的整型数组。所以p是⼀个指针,指向⼀个数组,叫数组指针。
// 这里要注意: [] 的优先级要⾼高于 * 号的,所以必须加上()来保证 p 先和 * 结合
数组指针的使用:
首先我们来看一段代码:
int arr[10] = {0};
arr;// 表示数组首元素的地址
&arr;// 表示数组的地址
// 具体差异在哪?
printf("%p\n", arr);
printf("%p\n", arr+1);
printf("%p\n", &arr+1); // 我们可以看出产生的结果是截然不同的
// 这里是因为数组的地址和数组首元素的地址值是相同的,但是意义不同。
那么数组的地址如何来存储?
int arr[10] = {0};
int*p1 = &arr;
int (*p2)[10] = &arr;
//很明显,p2是比较适合的选择
//p2是数组指针,所以存放数组的地址是合适的
如果我们要将一个二维数组传参,我们怎么做?
// 测试
void test()
{
int arr[3][5] = {0};
print(arr);// 这里 print 函数的参数如何设计?
}
void print(int arr[3][5])//ok?
{}
void print(int arr[][5])//ok?
{}
void print(int **arr)//ok? 数组的地址放到二级指针明显不合适
{}
void print(int (*arr)[5])//ok? 数组的地址放到数组指针是合适的
{}
上⾯我们了解了【数组指针】和【指针数组】之后我们看看下面的代码:
int arr[5]; //整形数组
int *parr1[10]; //指针数组
int (*parr2)[10]; //数组指针
int (*parr3[10])[5];
//存放数组指针的数组:parr3先和[]结合,说明是一个数组,有十个元素,
//每一个元素是数组指针,指向一个大小为5个整形的数组。
函数指针
⾸先看⼀段代码:
#include <stdio.h>
void test()
{
printf("hehe\n");
}
int main()
{
printf("%p\n", test);
printf("%p\n", &test);
return 0;
}
输出的是两个地址,这两个地址是 test 函数的地址。 那我们的函数的地址要想保存起来,怎么保存? 下面我们看代码:
void test()
{
printf("hehe\n");
}
// 下面 pfun1 和 pfun2 哪个有能力存放 test 函数的地址?
void (*pfun1)();
void *pfun2();
首先,能给存储地址,就要求pfun1或者pfun2是指针,那哪个是指针? 答案是:
pfun1可以存放。pfun1先和*结合,说明pfun1是指针,指针指向的是⼀个函数,指向的函数无参数,返回值类型为void。
函数指针数组、 函数指针的数组的指针
函数指针数组
数组是⼀个存放相同类型数据的存储空间,那我们已经学习了指针数组, 比如:
int *arr[10];
// 数组的每个元素是 int*
那要把函数的地址存到一个数组中,那这个数组就叫函数指针数组,那函数指针的数组如何定义 呢?
int (*parr1[10]])();
int *parr2[10]();
int (*)() parr3[10];
答案是:parr1
parr1 先和 [ ]结合,说明parr1是数组,数组的内容是什么呢? 是 int (*)() 类型的函数指针
函数指针数组的用途:转移表
例子:(计算器)
指向函数指针数组的指针
指向函数指针数组的指针是一个指针
指针指向一个数组 ,数组的元素都是函数指针 ;
如何定义?
void test(const char* str)
{
printf("%s\n", str);
}
int main()
{
// 函数指针 pfun
void (*pfun)(const char*) = test;
// 函数指针的数组 pfunArr
void (*pfunArr[5])(const char* str);
pfunArr[0] = test;
// 指向函数指针数组 pfunArr 的指针 ppfunArr
void (*(*ppfunArr)[10])(const char*) = &pfunArr;
return 0;
}