上部分内容只是浅显的了解了一下指针,接下来就要掌握一些进阶方面的知识了。
指针数组
其实本部分内容的重头戏在于数组指针以及它的使用,在总结数组指针之前先来了解一下什么叫做指针数组。指针数组,顾名思义是一个数组,指针数组就是一个存放指针的数组,其数组元素都为指针。
指针数组的定义方式是
int* arr[10];
我们可以在其中存放指针作为元素
int *arr[1]={&a}//将a的地址存放在指针数组arr里
int* arr1[10]; //整形指针的数组
char *arr2[10]; //一级字符指针的数组
char **arr3[10];//二级字符指针的数组
数组指针
数组指针顾名思义,是指针,它是一种指向数组的指针。来看它的定义方式:
int (*p)[10];
p先和星号结合,说明p是一个指针变量,然后指着指向的是一个大小为10个整型的数组。所以p是一个指针,指向一个数组,叫数组指针。这里要注意:[]的优先级要高于星号的,所以必须加上()来保证p先和星号结合。
数组指针的使用
可以用数组指针来输出数组中的元素,但是对于一维数组来说这没什么太大的意义,我们还是先来看一下代码,假如你想要输出一个一维数组的每个元素,定义一个函数来说明问题。
void Show1(int (*arr)[3],int n)
{
int i = 0;
for(i = 0;i < n;i++)
{
printf("%d ",arr[i]);
}
}
int main()
{
int arr[3]= {1,2,3};
show(arr, 3);
return 0;
}
用数组指针来接收参数,就解决了这个问题,但是没必要。
数组指针输出数组的意义在于二维数组中的使用。
void show2(int (*arr)[3], int row, int col)
{
int i = 0;
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
void show3(int arr[3][3], int row, int col)
{
int i = 0;
for(i=0; i<row; i++)
{
for(j=0; j<col; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
int main()
{
int arr[3][3]= {1,2,3,4,5,6,7,8,9};
show2(arr, 3);
show3(arr,3,3);
//show2,和show3的作用是相同的
return 0;
}
有读者会发现一个问题,为什么在show2函数中,形参是一个一维数组指针呢?
注意:数组名代表数组首元素,而二维数组的数组名代表的是二维数组的第一行元素。这里传递的arr代表的是二维数组整个第一行元素的地址,所以在show2函数的定义过程中需要用一个一维数组指针来作为形参。
数组名与&数组名 的区别
我们知道数组名的意义是数组首元素的地址,那么单独使用数组名与在它前面加上一个取地址符号&有什么区别呢?来通过代码找寻答案。
#include <stdio.h>
int main()
{
int arr[10] = {0};
printf("%p\n", arr);
printf("%p\n", &arr);
return 0; }
打印结果是一模一样的,让我们接着验证。
int main()
{
int arr[10] = {0};
printf("%d,%d\n",arr,&arr);
printf("%d,%d\n",arr+1,&arr+1);
return 0;
}
打印带有取地址的&arr+1以后,结果地址却加了整个数组的位数,而arr只是加了1,由此我们可以知道:&数组名代表整个数组的地址。由此我们可以总结一下:
数组名在两种情况下代表整个数组:
1、在运算符sizeof()中,sizeof(arr)代表的是整个数组的长度。
2、&数组名+1 代表整个数组的地址