参考借鉴(写得很好):链接:指针进阶之数组指针和指针数组-CSDN博客
一、指针数组(指针数组是数组,数组保存的是地址)
1.概念
指针数组是
数组
,用来存放指针的。
既然是地址,那么该地址解引用之后就可以得到原来存储的值。
案例一:
int main(){
int a=10;
int b=20;
int c=30;
int d=40;
int* arr[4]={&a,&b,&c,&d};
int i=0;
for(i=0;i<4;i++){
printf("%d ",*(arr[i]));
}
return 0;
}
案例二:
有了这样一个指针数组,我们就能很好的将三个数组维护起来。
一个一维数组(parr),维护了三个一维数组(arr1,arr2,arr3)。
int main(){
int arr1[]={1,2,3,4,5};
int arr2[]={2,3,4,5,6};
int arr3[]={3,4,5,6,7};
int* parr[]={arr1,arr2,arr3};
int i=0;
for(i=0;i<3;i++){
int j=0;
for(j=0;j<5;j++){
printf("%d ",*(parr[i]+j));
}
printf("\n");
}
return 0;
}
总结:通过parr[i]
找到存储的每个数组首元素地址,通过parr[i]+j
找到每个元素的地址,解引用找到每个元素。
二、数组指针(数组指针是指针,指针指向的是数组)
2.1概念
数组指针是
指针
,用来存放数组的地址。
既然要存放数组的地址
,就要有一个数组指针
。
定义一个指针变量p,里面存放数组的地址。
🚗 那该如何来写这个数组指针变量呢?
①这样写行吗:
int* p[10]=&arr;
这里的p是一个指针数组,int*
表示该数组里面存放的是整型指针类型的元素,p为数组名,[10]表示数组里面有10个元素。
为什么它是数组而不是指针?因为“[]”优先级比“*”高,p就是一个数组,里面存放指针。这样表示也不行!
我现在想表示的是一个指针!!!里面存放的是地址。
③那我们这样写:
int(*p)[10]=&arr;
既然第二种写法,“[]”的优先级比“*”高,导致p先与“[]”结合,成为了数组。
那我们可以用小括号,将*p包裹起来,让p先与*号结合,使p成为一个指针!
P前面是*,说明p是一个指针(定义变量的时候,*不是解引用操作),指向什么呢?
除去*p不看,剩下的是“int[10]数组类型。
[10]说明p指向的是一个数组,数组里面有10个元素。
int说明数组里面存放的是整型元素。
所以p是一个指针,指向的是一个数组,数组里面有10个元素,每个元素是int类型。
④综上所述,下面的p变量就有能力存放arr数组的地址。
int arr[10]={1,2,3,4,5,6,7,8,9,10}; //arr数组里面有10个元素,每个元素是int类型
int(*p)[10]=&arr;
//P为数组指针--> 是一个指针,用来存放数组的地址。指向的是一个数组,数组里面有10个元素,每个元素是int类型
(3)辨析
我们再来辨析一下:
①案例一
int* p1[10];
1
p1首先和[]结合,是一个数组。数组里面10个元素。每个元素是“int*”类型,p1是一个存放指针的数组。
②案例二
int(*p2)[10];
1
p2首先和*结合,是一个指针变量。指针指向数组,数组里面有10个元素,每个元素是int类型。
(4)总结
(1)int(*p)[10]
p先和*结合,说明p是一个指针变量,然后指向的是一个大小为10个整型的数组。
所以p是一个指针,指向一个数组,叫数组指针。
(2)注意
[]的优先级高于*,所以必须加上()来保证p先和*结合。
案例:(一维数组)
int main(){
int arr[10]={1,2,3,4,5,6,7,8,9,0};
int (*pa)[10]=&arr; //将数组arr的地址赋值给数组指针变量pa
int i=0;
for(i=0;i<10;i++){
printf("%d ",(*pa)[i]);
}
return 0;
}
案例:(二维数组)
数组指针要在二维数组以上使用
void print1(int arr[3][5], int x, int y) {
int i = 0;
int j = 0;
for (i = 0; i < x; i++) {
for (j = 0; j < y; j++) {
printf("%d ", arr[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} };//定义一个二维数组
//我想把这个二维数组打印一下
print1(arr,3,5);//封装一个函数,把数组名和行列传过去
return 0;
}
案例:
#include "stdio.h"
void print2(int (*p)[5], int x, int y) {
int i = 0;
for (i = 0; i < x; i++) {
int j = 0;
for (j = 0; j < y; 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;
}
总结
第一种写法,参数是数组的形式。
第二种写法,参数是指针的形式。