指向数组的指针,本质是指向数组第一个元素的地址。
1.指向数组的指针
在C语言中,我们将下标为第 0 个元素的地址称为数组的首地址。指向数组的指针,本质是指向数组第一个元素的地址。
例如:
#include <stdio.h>
#include <stdlib.h>
int main() {
int arr[]={99,15,100,888,252};
int *p = arr;
printf("数组第一个元素的地址:%d\n",&arr[0]);
printf("数组的首地址:%d\n",&arr);
printf("指针变量p的值:%d\n",p);
return 0;
}
运行结果:
数组第一个元素的地址:6487552
数组的首地址:6487552
指针变量p的值:6487552

2.使用指针遍历数组
实例:
#include <stdio.h>
#include <stdlib.h>
#define LEN(x) sizeof(x) / sizeof(x[0])
int main() {
int arr[]={99,15,100,888,252};
int *p = arr;
int len = LEN(arr);
/*方式一
for(int i=0;i<len;i++){
printf("%d ",*(p+i));
}*/
//方式二
for(int i=0;i<len;i++){
printf("%d ",*p);
p++;
}
return 0;
}
需要注意的是:数组的名字arr是指针常量,不允许改变值。因此通过自增arr的方法不能遍历数组。
例如:
#include <stdio.h>
#include <stdlib.h>
#define LEN(x) sizeof(x) / sizeof(x[0])
int main() {
int arr[]={99,15,100,888,252};
int *p = arr;
int len = LEN(arr);
for(int i=0;i<len;i++){
printf("%d ",*(arr+i)); //ok.
}
/*
for(int i=0;i<len;i++){
printf("%d ",*p);
arr++; //错误,arr是指针常量
}*/
return 0;
}
3.深入理解数组名
int arr[] = {1,2,3,4,5};
注意:arr本身不是一个指针变量,既然不是变量也就不需要另外存储空间,所以arr本身用&取地址是没有意义的,很多教材说数组名就是一个指向数组的一个元素地址的指针常量。这里要特别强调下,是指针常量,而不是常量指针,所以其本质就是个常量,而不是变量。其定义形式如下:
int * const pt;
通过这个定义也可以说明arr本身不是变量,arr本身不是地址而是指代整个数组,只不过会隐式转成指针罢了,array代表的是数组元素array[0]的地址。而&array代表的是整个一维数组的地址,这样就巧了出现arr,&arr和&arr[0]的值都相同。
但是arr与&arr表示的含义完全不同,&arr代表的是整个一维数组的地址,&arr用来计算下一个同样长度的数组开始的位置,它应从arr[0]开始,而arr代表的是数组第一个元素的地址。
看下面实例:
#include <stdio.h>
int main(int argc,char *argv[])
{
int arr[] = {1,2,3,4,5,6,7,8,9,10};
int *p = arr;
printf("%d\n",p);
printf("%d\n",*p);
printf("%d\n",&p);
printf("%d\n",&arr);
printf("%d\n",arr);
printf("%d\n",&arr[0]);
printf("\n------------------------\n");
printf("arr is %x, &arr is %x\n", arr, &arr);
printf("arr + 1 is %x, &arr +1 is %x\n", arr + 1, &arr + 1);
return 0;
}
运行结果:
6487536
1
6487528
6487536
6487536
6487536
------------------------
arr is 62fdf0, &arr is 62fdf0
arr + 1 is 62fdf4, &arr +1 is 62fe18