1.数组指针存在的意义
#include<stdio.h>
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int (*p)[10] = &arr;
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for(i=0;i<sz;i++)
{
printf("%d ",*(*p+i));//p是指向数组的,*p其实就是相当于数组名,数组名又是首元素的地址
//*p本质上是首元素的地址
}
return 0;
}
观察这一段代码
取出一维数组arr的地址,并定义一个数组指针p存放,而在打印一维数组arr时,*(*p+i)这样的表达方式难免过于繁琐了
转而观察这一段代码,定义一个指针数组p来打印数组arr好像更加简便,那这样一比较,数组指针存在的意义和作用又是什么呢?
#include<stdio.h>
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int* p = arr;
int i = 0;
for(i=0;i<10;i++)
{
printf("%d ",*(p+i));
}
return 0;
}
定义一个二维数组arr,并定义一个print函数来打印该二维数组
我们在传参时,分别以数组形式传参和指针形式传参
数组形式传参:
#include<stdio.h>
void print1(int arr[3][4],int r ,int c)
{
int i = 0;
for(i=0;i<3;i++)
{
int j = 0;
for(j=0;j<4;j++)
{
printf("%d ",arr[i][j]);
}
printf("\n");
}
}
int main()
{
int arr[3][4] = {1,2,3,4,2,3,4,5,3,4,5,6};
print1(arr,3,4);
return 0;
}
指针形式传参:
#include<stdio.h>
void print2(int(*p)[4],int r ,int c)
{
int i = 0;
for(i=0;i<r;i++)
{
int j = 0;
for(j=0;j<c;j++)
{
//printf("%d ",*(*(p+i)+j));
//*(p+i)->p[i]
printf("%d ",p[i][j]);
}
printf("\n");
}
}
int main()
{
int arr[3][4] = {1,2,3,4,2,3,4,5,3,4,5,6};
print2(arr,3,4);
return 0;
}
观察这两种不同形式的传参,我们知道二维数组名指向第一行数组(首元素)的地址,即一个一维数组的地址,我们在传参时,定义一个数组指针p来存放第一行数组(首元素)的地址,即二维数组的地址,再来打印该二维数组
在使用函数传参时,我们都知道从内存的时间复杂度和空间复杂度来考量,首选指针变量传地址的方式,而在传二维数组首元素地址时,数组指针的作用便体现的淋漓尽致。相信数组指针的用处不止一点,期待探索更多相关知识。
2.数组指针中针对(&数组名)以及(数组名)二者的区别
数组名通常表示的都是数组首元素的地址
但是有2个例外:
1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小
2.&数组名,这里的数组名表示的依然是整个数组,所以&数组名取出的是整个数组的地址
拆分理解数组指针:
int(*p)[4];
p 的类型是int(*)[4]
p 是指向一个整型数组的,数组有4个元素
p+1-->跳过一个存有4个int类型元素的数组
理解&arr和arr的区别
int arr[10];
int(*p)[10] = &arr;
定义一个int类型的数组arr,并定义一个数组指针p将其地址储存起来
int* p2 = arr;
再定义一个int类型的指针数组p2将数组首元素地址存储起来
p2+1-->跳过一个整型元素(4个字节) arr-->int*
&arr+1-->跳过10个整型元素(40个字节) &arr-->int(*)[10]
我们知道指针类型决定了在+-1时,指针的权限(步长)的大小