1、 数组指针–>指针
- 先观察整形指针和字符指针,然后引入数组指针
int *p = NULL;// 整形指针--指向整形的指针--可以存放整形的地址
char *pc = NULL;// 字符指针--指向字符的指针--存放字符的地址
// 数组指针--指向数组的指针--存放数组的地址&arr(数组是一种数据类型,自定义数据类型)
int arr[10] = {0};
// arr - 首元素地址
// &arr[0] - 首元素地址
// &arr - 数组的地址--如何存储数组的地址?就是数组指针
int (*p)[10] = &arr; // p就是数组指针
char* arr[5];
char*(*p)[5] = &arr;
// *p表示p是指针 [5] p指向的数组是5个元素 char*--> p指向数组的元素类型是char*
数组指针的使用
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\n",(*p)[i]);// *p 表示整个数组,其实就是相当于arr; &*相互抵消的样子
}
数组指针这种使用很不方便,只有当数组是二维数组及以上时,使用这个才好用
int arr[3][5] = {{1,2,3,4,5}, {2,3,4,5,6}, {3,4,5,6,7}};
my_print(arr, 3, 5);
// 参数是数组的形式
void my_print1(int arr[3][5], int x, int y) {
int i = 0;
int j = 0;
for (){
for(){
printf();// 这种方式传统的打印
}
}
}
// 其实传递的参数arr,是个首元素地址,需要用指针来接收,但对于二维数组来说,数组的首元素并不是第一行第一列的那个元素!!
// 二维数组,首先要把二维数组想象成一维数组!!!
// 把每一行当做一个元素!所以首元素地址是第一行!!!也就是一维数组的地址,要用数组指针来存!!!
// 参数是指针的形式
void my_print2(int(*p)[], int x, int y){ // 二维数组传递的首元素地址,是一维数组的地址,指向数组的指针,是数组指针;此时如果 p+1 就是跳过一整个数组,就是第二行了!!!
int i = 0;
for(i = 0; i < x; i++) {
int j = 0;
for(j = 0; j < y; j++) {
printf("%d ", *(*(p+i)+j);// *(p+i) 第i行
//(*(p + i))[j] --> 其实也是一样的
// 这个理解:也就是说对于 int *p = arr; 这个代码,本身就是arr赋值给p,就是arr和p是一回事,可以理解为指针就是数组名 *(p + i) == *(arr + i) == arr[i] == p[i]
}
}
}
需要注意的是,二维数组的首元素是一个一维数组,而不是左上角的第一个元素,因此二维数组的首元素地址是一维数组的地址,因此需要使用数组指针来接收
2、指针数组–>数组(存放指针的数组)
指针数组就简单多了
int arr[10] = {0}; // 整形数组
char ch[5] = {0}; // 字符数组
int* arr[4]; // 存放整形指针的数组
作用:
int arr1[] = {1,2,3,4,5};
int arr2[] = {2,3,4,5,6};
int arr3[] = {3,4,5,6,7};
// 一个一维数组,维护了三个数组
int* p[] = {arr1, arr2, arr3};
注:
比较好的区分是指针数组还是数组指针,就看*
是和谁结合,比如:
int (*)[10]
*
是放在括号里面,所以代表这是一个指针,所以是数组指针,数组大小是[10]
,存放的数据类型是int
int *[10]
*
是和int
结合,表示一个int*
也就是整形指针类型,譬如char
数组类型int
整形类型一样,这是一个整形指针类型,后面有个[10]
数组,表示这是一个指针数组,数组中存放的是int*
类型的数据。