(易混淆点)带你理清数组和指针之间的关联

致读者

数组名和指针有何关联?访问数组元素的方括号[ ]和指针有何关联?请一点点的往下阅读——

指向数组元素的指针

指向数组元素的指针,也就是数组元素的地址,它们展现出怎样的特点,或者说,规律呢?
以下面这段代码为例:

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——白龙码

猜你喜欢

转载自blog.csdn.net/Wyf_Fj/article/details/113800796