指针数组,顾名思义就是用来存放指针的数组。
下面是一些指针数组的简单例子。
int main()//诸如此类就是指针数组
{
int a = 1, b = 2, c = 3, d = 4;
int* pa[4] = { &a,&b,&c,&d };//数组元素为整型指针
char* pch[10] = { 0 };//数组元素为字符指针
int** Ppa = {0};//数组元素为二级指针
return 0;
}
指针数组的应用:存放数组首元素地址。
我们知道,数组名为数组的首元素地址,我们可以创建一个数组Parr来存放其他数组名。
int main()
{
int arr1[] = { 1,2,3,4,5 };
int arr2[] = { 6,7,8,9,0 };
int arr3[] = { 4,5,6,7,8 };
int* Parr[] = {arr1,arr2,arr3};
int i = 0, j = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 5; j++)
{
printf("%d ", *(Parr[i] + j));
}
printf("\n");
}
return 0;
}
数组指针,即数组的指针,指针指向的内容为数组·。
首先我们要明确,一个存放10个整型的数组arr[10],这个数组的数据类型为 int [10]
数组指针的定义方法 *int(p)[10] = &arr; p为数组指针;
(*p)外边的是指针指向对象的类型 int [10];
()内*p代表它是指针;
p是指针变量的名字;
下面我们上代码来展现数组指针:
int main()
{
int* pa = NULL; //pa 是整形指针 - 指向整形的指针 - 可以存放整形的地址
char* pch = NULL; //pch是字符指针 - 指向字符的指针 - 可以存放字符的地址
//同理:数组指针 - 指向数组的指针 - 存放数组的地址
//arr - 首元素地址
//&arr[0] - 首元素地址
//&arr - 数组的地址
int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
int* p0 = arr; //这是取数组首元素地址
int(*p)[10] = &arr; //数组指针p用int(*p)[10]表示,其中int[10]是数组的类型
//若上述p的类型为int* p,就无法与整形指针区别;若int *p[10],[]的优先级比*高,先和[]结合,表示存放指针的数组;
return 0;
}
区分下面p1 p2是什么类型?
int *p1[10]
int(*p2)[10]
int *p1[10] ---- 存放指针的数组 – 指针数组
int(*p2)[10] — 指向数组的指针 – 数组指针 // p2的类型是 int(*)[10]
pa为&arr,请写出pa的类型声明
int main()
{
char* arr[5];
return 0;
}
答案:char* (*pa)[5] = &arr;
(*pa)代表pa变量为指针;外面的char* [5]是指针指向对象的类型 。
区分下面是什么 ?
注:做下面题目的核心思想为 [ ] 优先级比 * 高
int *p //是一个指针,指向整形
int arr[5] //是一个5个元素的整形数组
int *parr1[10] //是一个数组,有10个元素,元素类型是int*,parr1是指针数组
int (*parr2)[10] //是一个指针,指向一个有10个整形元素的数组 //parr2的类型为 int(* )[10]
int (*parr3[10])[5] //是一个有10个元素的数组,每个元素是个数组指针,指向有5个整形元素的数组
数组指针的简单应用
数组指针int(*p)[10]=&arr; *p的作用相当于arr
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
int(*pa)[10] = &arr;
int i = 0;
for (i = 0; i < 10; i++)
{
//用法1,arr[i]变成(*p)[i],相当于arr[i]
printf("%d", (*pa)[i]);
}
for (i = 0; i < 10; i++)
{
//用法2,pa解引用为*pa,相当于arr,可以当首元素地址使用
printf("%d", *(*pa + i));
}
}
数组指针具体应用
我们直接上代码:
(下面代码的原理是:二维数组名 为 第一行的一维数组的地址)
void pri1(int ARR[3][3], int x, int y)//(参数的数组的形式)
{
int i, j;
for (i = 0; i < x; i++)
{
for (j = 0; j < y; j++)
{
printf("%d ", ARR[i][j]);
}
printf("\n");
}
}
//二维数组int arr[3][3]传参,传的是(二维数组首元素)地址 ,是(一维数组)的地址,是int(*p)[3]
void pri2(int(*p)[3], int x, int y)//(参数是指针的形式)
{
int i, j;
for (i = 0; i < x; i++)
{
for (j = 0; j < y; j++)
{
/因为p[i]是以p为首元素地址访问下标为i的元素 == *(p+i)
//所以可以写成下面几种形式
printf("%d ", *(*(p + i) + j));
printf("%d ", (*(p + i))[j]);
printf("%d ", *(p[i] + j));
printf("%d ", p[i][j]); //相当于(p[i])[j] == (每行的数组名)[j]
}
printf("\n");
}
}
int main()
{
int arr[3][3] = { {1,2,3},{4,5,6},{7,8,9} };
pri1(arr, 3, 3);//数组名传参,数组形式接收
printf("\n");
//arr -- 二维数组名 -- 首元素地址
//二维数组的首元素是什么?
//这里要把二维数组看作一维数组,每一行(每一个{})看作一个元素
//那么arr[3][3]有三个元素,每一行是一个元素
//那么{{1,2,3},{4,5,6},{7,8,9}}的首元素就是{1,2,3},是一维数组
//二维数组数组名是首元素地址,就是第一行的地址,是一个一维数组的地址
pri2(arr, 3, 3);
printf("\n");
return 0;
}
下标引用操作符[]的本质 *(p + i)
p为指针,p[i]表示 – 以p为起始地址,访问下标为i的元素
p[i] == *(p + i)
int main()
{
int arr[5] = { 1,2,3,4,5 };
int* p = arr;
int i = 0;
for (i = 0; i < 5; i++)
{
printf("%d ", arr[i]);//数组名+下标引用操作符
printf("%d ", *(arr + i));//数组首元素地址+下标,解引用
printf("%d ", *(p + i));//和上一个一样
printf("%d ", p[i]);//以p为起始地址,访问下标为i的元素
//由上面得出,p[i] == *(p + i)
printf("\n");
}
return 0;
}
传参时,可以在形参部分写【数组】或【指针】
void test1(int arr1[])//拿数组接收,可不写大小
{ }
void test2(int arr1[10])//拿数组接收
{ }
void test3(int *arr1)//拿指针接受
{ }
void Test1(int *arr2[20])//拿数组接收
{ }
void Test2(int **arr2)//拿指针接收
{ }
int main()
{
int arr1[10] = { 0 };
int* arr2[20] = { 0 };
test1(arr1); test2(arr1); test3(arr1);
Test1(arr2); Test2(arr2);
return 0;
}
void test1(int arr[3][5])//用数组来接收
{ }
void test2(int arr[][5])//二维数组行可以省略,列不可以省略
{ }
void test3(int(*arr)[5])//用二维数组的首元素地址(第一行一维数组的地址)来接收
{ }
int main()
{
int arr[3][5] = { 0 };
test1(arr);
test2(arr);
test3(arr);
return 0;
}
void test(int *p)//用指针接收
{ }
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
int x = 10;
int* pa = arr;
int* px = &x;
test(pa); //可传 指针变量
test(arr); //可传数组首元素地址
test(px); //可传指针变量
test(&x); //可传变量地址
return 0;
}
void test(int** p)//用二级指针接收
{ }
int main()
{
int* arr[10];
int** pa = arr;
int n = 10;
int* p = &n;
int** Pp = &p;
test(Pp); //可传二级指针变量
test(&p); //可传一级指针的地址
test(arr); //可传指针数组首元素地址
test(pa); //可传二级指针变量
return 0;
}