数组与指针
以int arr[] = { 99, 15, 100, 888, 252 };
为例,该数组在内存中的分布如下图所示:
定义数组时,要给出数组名和数组长度,数组名可以认为是一个指针,它指向数组的第 0 个元素。在C语言中,我们将第 0 个元素的地址称为数组的首地址。以上面的数组为例,下图是 arr 的指向:
数组名的本意是表示整个数组,也就是表示多份数据的集合,但在使用过程中经常会转换为指向数组第 0 个元素的指针,所以上面使用了“认为”一词,表示数组名和数组首地址并不总是等价。
指针使用
首先我们得了解指针的几种形式
先上代码:
int main(){
int arr[] = { 99, 15, 300, 888, 252 };
int *p = arr;
printf("*p+1 ==> %d\n",*p+1);
printf("*(p+1) ==> %d\n",*(p+1));
printf("p+1 ==> %d\n",p+1);
printf("p ==> %d\n",p);
printf("*(arr+1) ==> %d\n",*(arr+1));
printf("*(&arr+1) ==> %d\n",*(&arr+1));
printf("*arr+1 ==> %d\n",*arr+1);
printf("arr+1 ==> %d\n",arr+1);
printf("arr ==> %d\n",arr);
printf("&arr ==> %d\n",&arr);
}
输出结果:
*p+1 ==> 100
*(p+1) ==> 15
p+1 ==> 6422284
p ==> 6422280
*(arr+1) ==> 15
*(&arr+1) ==> 6422300
*arr+1 ==> 100
arr+1 ==> 6422284
arr ==> 6422280
&arr ==> 6422280
int arr[] = { 99, 15, 300, 888, 252 };
要了解指针,得先记住这样的前提条件:
p == arr == &arr[0]
是数组的首地址,而*p == *arr == arr[0]
是数组的第一个元素。
然后我们把对应的等价替换掉——
*p+1
和*arr+1
这个简单,就是直接取值加1,相当于arr[0]+1==100;
*(p+1)
和*(arr+1)
根据运算符优先级,先看括号内,p+1,也就是数组的首地址+1。
地址+1,可以理解为下一个元素,相当于arr[0+1]== arr[1] ==15
p+1
和arr+1
p == arr == 6422280 ,但是p+1 == arr+1 == 6422284,这说明地址+1并不是简单的值+1。
那为什么是4?
因为数组的类型是int,sizeof(int)=4。
*(&arr+1)
arr,&arr的地址是一样的,但代表的含义不一样了。
arr是数组首地址,也就是arr[0]的地址,&arr是对象(数组)首地址。arr+1是数组下一元素的地址,即arr[1],&arr+1是下一个对象的地址,即arr[6]。
简单来说: *(arr+1)是从数组首地址跳跃一个int的长度,也就是下一个数组元素;而*(&arr+1)是从首地址跳跃一个数组的长度,也就是数组最后一个元素的下一个位置
总结
*p == *arr == arr[0] ----> 数组首个元素
arr == p ==&arr[0] ---->数组首地址
*(p+1) == *(arr +1) == arr[0+1] ---->下一个元素
*p+1 == arr[0]+1 ---->值+1
*(&arr +1) ----->下一组元素
*p++ == *(p++) ----> 先取值再自增
*++p == *(++p) ----> 先自增再取值
(*p)++ == arr[0]+1 ---->首个元素的值+1