一、概念
下面哪个是数组指针?
int *p1[10];
int (*p1)[10];
int (*p)[10];
解释:p先和*结合,说明p是一个指针变量,然后指向一个大小为10的整型数组,所以p是一个指针,指向整型数组,叫做数组指针。
注意:【】的优先级要高于号,所以必须加上()保证先跟p结合,形成指针,不然就是一个整型数组。
举个例子:
double *d[5]
写出他的数组指针。
书写顺序:
- 先写指针,说明这是一个指针变量,注意要用括号括起来!(*pd)
- 然后写出指向数组的元素个数 (*pd)[5]
- 最后写出指向这个数组的类型,写在最前面。 double* (*pd)[5]
总结:
先写中间,后写两边。
二、&数组名VS数组名
数组名只是单纯指向数组第一个元素的地址。
而&数组名是整个数组的地址
数组名+1跳过了一个元素,而&数组名+1直接跳过整个数组!
TIP:
数组名不是数组首元素地址的两个意外
1、sizeof(数组名)计算的是整个数组的大小,单位是字节
2、&数组名,表示整个数组,取的是整个数组的地址
三、数组指针的应用
一般用于二维数组的遍历。
代码的实现:
void print2(int (*p)[5],int r,int j)
{
//p表示二维数组第一行的地址
for (int i=0;i<r;i++)
{
for (int k=0;k<j;k++)
{
printf("%d ", *(*(p + i) + k));
}
printf("\n");
}
}
int main()
{
int arr[3][5] = { {1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7 } };//二维数组的初始化
print2(arr, 3, 5);//二维数组的首元素是第一行!
return 0;
}
解析:
二维数组的数组名表示第一行数组的地址!
所以p表示二维数组的第一行元素的地址,*(p+i)表示第几行,而*(*(p+i)+k)就表示每一行的每一个元素,既可以遍历。
三、练习
看看下面的代码表示什么含义?
第一个表示普通的整型数组
第二个表示存放指针的数组——指针数组
第三个表示数组指针,指向整型数组
第四个比较难。
思考方式:
首先他优先跟【】结合,所以本质是一个数组。
举个简单的例子:int arr[10]。
我们把数组名和【】都去掉,剩下的就是数组的类型!
我们也这么思考,把parr[10]去掉,此时剩下int (*)[5],所以就是一个数组指针,也就是这是一个数组,存放数组指针的数组!
该数组能够存放10个数组指针,每个数组指针能够指向一个数组,数组5个元素,每个元素是int类型。
四、一维数组、二维数组的传参
一维数组传参时如果用数组接收,初始化或者不初始化都可以。
最后一个取的是一级指针的地址,所以要用二级指针接收,正正好。(本身数组名就是首元素的地址)
总结:
数组传参时,形参一般分两种情况接收。
第一种以数组的形式接收,第二种以指针的形式接收(因为数组名也可以看成首元素的地址)
若以数组的形式接收,一维数组初始化与不初始化都可以。
二维数组必须要列初始化。
若以指针的形式接收,二位数组的数组名表示第一行的地址,因此一般就用数组指针接收!