前言:
看到标题的小伙伴可能会有点疑惑,什么是指针数组,数组指针??傻傻分不清楚,不怕,听我慢慢道来。
正文:
要想弄清楚这两个概念,我们不妨举几个例子:
1、数组:
int arr[5] = {1,2,3,4,5};
这就是最简单的数组,数组中每个元素都是int类型,下面的图片帮助大家很容易理解。
数组可以将相同类型的数据整合到一起,你可以通过下标的方式或者指针的方式来访问,在这里不多赘述。
2、指针数组:
int *parr1[10]
形如以上形式的,叫做指针数组,其中:paar1先与[10]结合为parr1[10],为一个有10个元素的数组,其次再与int*结合,及每个元素的类型是int*。以下图片更方便大家理解:
注意:指针数组,本质上parr1是数组,因为优先级的关系,parr1先与[]结合,但是接下来要介绍的数组指针正好相反。
3、数组指针
int(*parr2)[10]
在第2点已经说过,数组指针因为()的缘故,优先级很高,所以parr2先与*结合为指针,并且是指向数组的指针,后面的[10]表示指向的数组里面有10个元素,每个元素为int型。下面的图更方便大家理解:
注意:此时的parr2是一个指针,如果把指针名parr2去掉,剩余的部分就是指针类型,:int(*)[10]
这就是数组指针,其实并没有想象的那么神秘!
4、数组指针的应用
这里为大家分享一下数组指针的几个小应用。
- 数组指针一般 = 右侧是整个数组的地址;
- 当数组指针指向一维数组的时候(当然基本上没人这么用),形式如下:
int(*pa)[5] = &arr
注意:
- 这里pa是数组指针,指向数组中有5个元素,数组元素是int型。
- &+数组名就是整个数组的地址,其数值上虽然与首元素地址相同,但是意义完全不一样。
- pa指针指向的是整个数组的地址,那么*pa(将指针解引用)取出的是整个数组的地址(也是数组首元素的地址)
- **pa取出的是第一个元素,与*pa[0]的效果等价。
- 当数组指针指向二维数组中时,这个用法很常见,有些书上面称这种指针为行指针,顾名思义就是操纵一行的指针,形如:
void print_arr2(int(*arr)[5], int row, int col){int i = 0;int j = 0;for (i = 0; i < row; i++){for (j = 0; j < col; j++){printf("%d ", arr[i][j]);}printf("\n");}}int main(){int arr[3][5] = { 1,2,3,4,5,6,7,8,9,10 };//数组名arr,表示首元素的地址//但是二维数组的首元素是二维数组的第一行//所以这里传递的arr,其实相当于第一行的地址,是一维数组的地址//可以数组指针来接收print_arr2(arr, 3, 5);return 0;}
运行结果:
注意:
- 上述代码我们定义了一个3行5列的二维数组,需要注意的是,二维数组可以不写明行,但是必须写明列,这里我们用数组指针来接收,也必须注明是5列,这是为了告诉内存第二行在哪里开始存放
- 我们将arr数组名传参过去,在一维数组中arr数组名代表首元素的地址,但在二维数组中,arr数组名代码的是第一行的地址,所以这也是行指针的由来。
- 形参中的int(*arr)[5]中存放的是:二维数组第一行的地址,也就是说arr代表的是第一行的地址。
- *arr就是二维数组第一个元素的地址,本代码也就是1的地址;**arr才找到第一个元素,即1。
- (arr+1)是第二行的地址,*(arr+1)是第二行首元素的地址,*(*(arr+1))是第二行首元素,即6。
结语:
想必大家看过我的blog应该对数组指针与指针数组有了初步的了解
这也是我本人第一次写blog,还请各位大佬手下留情!
最后,放一道思考题:
请问以下代码代表什么意思:
int(*parr3[10])[5]
答案就是:
- paar3是一个数组,数组中有10个元素,每个元素的类型是:int(*)[5];
- paar3是存放数组指针的数组。