(易混淆点)带你理清数组和指针之间的关联
作者:互联网
致读者
数组名和指针有何关联?访问数组元素的方括号[ ]和指针有何关联?请一点点的往下阅读——
指向数组元素的指针
指向数组元素的指针,也就是数组元素的地址,它们展现出怎样的特点,或者说,规律呢?
以下面这段代码为例:
int main()
{
int arr[10];
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for(i=0;i<sz;i++)
printf("&arr[%d]=%p\n",i, &arr[i]);
return 0;
}
输出结果为:
我们知道,地址在内存以十六进制数存放
首元素地址: 012FFA60
与第二个元素的地址:012FFA64 相差了4
第二与第三个的地址:012FFA68 相差了4
由此可见,指向数组元素的指针是连续的,且间隔1个元素的大小(这里是整型数组,元素大小为4字节);
数组名和数组地址和元素地址
看到这个标题,你是否想起了曾经被支配的恐惧?别怕,让我再捋一遍——
以代码入手:
int main()
{
int arr[10];
printf("%p\n", arr);
printf("%p\n", &arr);
return 0;
}
让我们看一下输出结果:
数组名arr居然和&arr的值一毛一样???是否可以认为,它们是一个东西?
答案是:NO!!!
在之前的博客我介绍过一次:数组名在多数情况下,表示的是首元素的地址,我们来看:
但是两种情况除外,我们首先介绍第一种情况,也就是sizeof(arr),在这里,arr代表的是整个数组,所以sizeof(arr)计算的就是整个数组的大小,我们来看:
第二种情况,牵扯到&arr和arr的关系:
我们刚才也看到了,&arr和arr以%p格式化打印的结果是一样的,但这仅仅意味着它们在数值上相同,区别在哪里?看下面这段代码:
int main()
{
int arr[10];
printf("%p\n", arr+1);
printf("%p\n", &arr+1);
return 0;
}
输出结果:
what?同样是加一,arr+1在原来首元素的基础上增加了4,但是&arr+1居然增加了40!
(不知道为什么是40的是十六进制还没弄清楚哦,可以看看我前面《详解数据存储(上)——进制》这篇文章)
这个结果就牵扯到&arr和arr的区别了:
arr是数组名,一般情况下数组名等价于首元素地址。这里元素类型为int,所以元素指针类型为int*,int*的步长为4,也就是说,它加1,相当于访问越过4个字节后的地址,4个字节也就是一个元素的大小,那么我们也可以理解为,arr+1后访问第二个元素。所以arr+1在arr的数值基础上加了4。
但是&arr拿到的是整个数组的地址,当它加一,相当于越过整个数组后访问。也就是,访问数组最后一个元素之后的那个地址,所以他在arr的数值基础上,增加了40,也就是整个数组的大小!!!
讲到这里先小小总结一下:
1、数组名是首元素的地址,即语句arr==&arr[0]成立(有两个例外)
①sizeof(arr)中arr表示整个数组,所以sizeof(arr)计算的是整个数组的大小,单位是字节;
②&arr中arr代表整个数组,&arr取出的是整个数组的地址;
如:printf("%p “, &arr+1)打印数组最后一个元素的后一个地址;
而 printf(”%p ", arr+1)打印的是第二个元素的地址;
2、int* arr和int arr[]都表示arr是一个指向int的指针,但int arr[]只能用于声明形式参数,如int fun ( int arr [ ] );
3、数组中元素地址+1表示下一个元素的地址;
如:printf("%p “, &arr[1]);
和printf(”%p\n", &arr[0]+1);
输出的结果相同,都是第二个元素的地址
利用指针访问数组元素
参照以下代码:
int main()
{
int arr[5] = { 1,2,3,4,5 };
int i = 0;
for (i = 0; i < 5; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
这里我们通过arr[ i ]的形式访问数组的第i-1个元素;
同样,我们还可以用第二种方式:
int main()
{
int arr[5] = { 1,2,3,4,5 };
int i = 0;
for (i = 0; i < 5; i++)
{
printf("%d ", *(arr + i));
}
return 0;
}
通过上面的学习,我们知道,arr+i就是数组首元素后的第i个元素的地址,通过对他的解引用,我们获得了数组首元素后的第i个元素,也就是第i+1个元素;
综上我们知道,arr[ i ]等价于* (arr + i) ,也就是arr[ i ]==* (arr + i)成立,这一点对于利用指针访问二维数组有大作用!(下一篇我们继续讲哦)
//创作不易,点个赞再走呗by——白龙码
标签:混淆,arr,int,元素,地址,理清,数组,printf,指针 来源: https://blog.csdn.net/Wyf_Fj/article/details/113800796