目录
指针数组:
整形数组里面存放的元素是整形,同理,指针数组里面存放的是指针。
先看一下指针数组:
int main()
{
int arr[10] = { 0 };//整形数组
char ch[5] = { 0 };//字符数组
int* parr[4];//存放整形指针的数组 - 指针数组
int a = 10;
int b = 20;
int c = 30;
int* p[3] = { &a,&b,&c };
int arr1[] = { 1,2,3,4,5 };
int arr2[] = { 2,3,4,5,6 };
int arr3[] = { 3,4,5,6,7 };
int* pa[] = { arr1,arr2,arr3 };//因为每个数组名就是地址,所以就是指针类型
return 0;
}
指针数组本质上是数组,数组里面存放的是指针,所以要加*,由于数组名是首元素地址,所以相当于指针。
这是指针类型的数组,数组里面存档的是指针。
我们来用指针数组模拟二维数组:
实际上并非是二维数组,因为每个指针不是连续存放的。
数组指针:
我们知道整形指针,字符型指针,正如有整形数组,字符型数组一样,也有数组指针。先看看如何用指针打印出每个元素:
int main()
{
int arr[] = { 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;
}
上面就是相当于定义了一个整形指针,我们来看数组指针的具体实现:
int main()
{
int arr[10] = { 1,2,3,4,5 };
int(*parr)[10] = &arr;//因为我们知道,&arr是整个数组的地址
//但是整个数组的地址是数组指针,并不是整形或其他类型,因此我们需要使用数组指针来接受
//int *parr[10],因为[]的优先级大于*,这样写相当于指针数组
return 0;
}
我们一定要知道&arr和arr(arr是数组名)的区别,arr是取出数组的首元素地址;&arr是取出整个数组的地址,因为数组指针指向整个数组,指针的步长就是一个整个数组,所以将parr+1下一个指向就是数组末元素的下一个地址。
int main()
{
int arr[10] = { 0 };
int* p1 = arr;
int(*p2)[10] = &arr;
printf("%p\n", p1);
printf("%p\n", p1 + 1);
printf("%p\n", p2);
printf("%p\n", p2 + 1);
return 0;
}
因为地址加上元素个数就是下一个地址,解引用后就会找到这个元素。 我们来看数组指针的使用:
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int(*p)[10] = &arr;
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", (*p)[i]);//p是数组的地址,想拿到元素只能解引用
}
for (i = 0; i < 10; i++)
{
printf("%d ", *(*p + i));//*p == arr->数组名,相当于首元素地址所以要解引用
}
return 0;
}
当p加上星号以后,就相当于把取地址&arr的&抵消掉了,之后就相当于数组名了,之后在后面加上下标,就把每一个元素打印出来了;之后第2种方法:*(*p+i)就相当于数组名是地址,解引用后找到每一个元素,加i就相当于下一个元素。
我们在给出一个比较绕的代码:
int main()
{
char* arr[5];
char* (*p)[5] = &arr;
return 0;
}
二维数组的传参:
当我们对二维数组进行函数传参时,因为二维数组的首元素是第一行的地址,因为二维数组可以当做几个一维数组组成。所以当使用二维数组进行传参时,我们传入数组名,就是第一行一维数组的地址,所以函数要使用数组指针进行接收。
void print2(int(*p)[5], int r, int c)
{
int i = 0, j = 0;
for (i = 0; i < r; i++)
{
for (j = 0; j < c; j++)
{
printf("%d", *(*(p + i) + j));
}
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;
}
一般数组指针是在二维数组上使用的,特别是函数传参。因为此时数组指针指向的数组个数为5,所以先对其解引用*找到上一个数组的地址(本质上就是二级指针),之后再让上一个数组地址找到它每个对应的元素,最后进行解引用即可。
我们可以观察每一行的地址。