数组指针
数组指针的定义
数组指针是指针?还是数组?
答案是:指针。
指针的类型
整形指针: int * p; 能够指向整形数据的指针,可以存放整形的地址
字符指针: char * p;能够指向字符数据的指针,可以存放字符的地址
浮点型指针: float * p; 能够指向浮点型数据的指针,可以存放浮点型的地址
数组指针:能够指向数组的指针,可以存放数组的地址
arr不同地方不同意义
int arr[10]={0};
arr-首元素的地址
&arr[0]-首元素的地址
&arr-数组的地址
数组指针
int arr[10]={1,2,3,4,5,6,7,8,9,10};
int(*p)[10] = &arr;//数组的地址要存起来
//上面的p就是数组指针
//p先和*结合,说明p是一个指针变量,然后指着指向的是一个大小为10个整型的数组
//[]的优先级要高于*号的,所以必须加上()来保证p先和*结合
例子:
char* arr[5];
char*(*pa)[5]=&arr;
pa-变量名字
*pa-指针
[5]-pa指向的数组有5个元素
char*-pa指向的数组的类型是char*
&数组名VS数组名
arr是数组名,数组名表示数组首元素的地址。
&arr和arr,虽然值是一样的,但是意义应该不一样的。
&arr 表示的是数组的地址,而不是数组首元素的地址
数组的地址+1,跳过整个数组的大小// &arr+1
数组指针的使用:二维数组以上才方便些
简单例子:
#include<stdio.h>
int main()
{
int i = 0;
int arr[5] = { 0 };
for (i = 0; i < 5; i++)
{
arr[i] = i;
}
int(*p)[5] = &arr;
for (i = 0; i < 5; i++)
{
printf("%d ", *(*p + 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");
}
}
//参数是指针的形式
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));
//写法2:printf("%d ",(*(p+i))[j]);
//写法3:printf("%d ",*(p[i]+j);
//写法4:printf("%d ",p[i][j];
}
}
}
/*
类比解析
int i=0
int* p =arr;
*(p+i)==*(arr+i)==arr[i]==p[i]
解析
*(*(p+i)+j)==(*(p+i))[j])==*(p[i]+j)==p[i][j]
p+i是数组指针,*可以拿到这个数组首元素地址
*/
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);//数组名就是首元素地址(sizeof和&arr除外)
print2(arr,3,5);//把arr想象成一维数组,首元素为{1,2,3,4,5}的地址,传过去是一位数组的地址
}
深入理解
int arr[5];//arr是一个5个元素的整形数组
int *parr1[10];//parr1是一个10个元素的数组,每个元素类型为int*,parr1是指针数组
int (*parr2)[10];//parr2是指针,指向10个元素的数组,数组类型是int,parr2是数组指针
int (*parr3[10])[5];//parr3是一个10个元素的数组,每个元素是一个数组指针,该数组指针指向的数组有5个元素,该数组的类型是int
详解:
int (* )[5];//数组类型:数组指针
parr3[10]//数组名[元素个数]