数组名不作为首元素地址的两种特殊情况

目录

情况一:数组名作为sizeof()的参数

情况二:&数组名


我们知道,数组名在绝大多数情况下表示的是数组首元素的地址。数组,无论是一维数组还是二维数组,其在内存中都是连续存放的。因此,通过访问该数组的首元素地址就可以访问数组的全部元素。

可是,在实际运用中,有两种特殊情况,数组名并不代表首元素的地址,而是代表整个数组。接下来让我们一起解析一下。

情况一:数组名作为sizeof()的参数

我们来看以下的代码:

#include <stdio.h>
int main()
{
	int arr[10] = { 0 };
	int p = sizeof(int);
	int t = sizeof(arr);
	printf("%d\n", p);
	printf("%d\n", t);
	return 0;
}

运行该代码:

我们发现,如果arr在这里代表的是首元素地址,那么t的值应该跟p的一致。然而t的值是p的十倍,且数组中恰好有十个元素。因此我们可以得出第一种情况:当数组名作为sizeof()的参数时,数组名代表的是整个数组,sizeof()得到的结果是整个数组所占内存大小。

但这种说法并不完整!

 我们再来看下面一段代码:

#include <stdio.h>

int test(int* str)
{
	return sizeof(str);
}
int main()
{
	int arr[10] = { 0 };
	int p = sizeof(int);
	int t = test(arr);
	printf("%d\n", p);
	printf("%d\n", t);
	return 0;
}

运行结果:

我们发现,假如将数组名作为参数传给另一个函数所执行,结果打印出的却是8

8是怎么来的呢?

这里的8所代表的是地址所占内存大小为8个字节。由于以上代码是在64位环境下运行,所以内存占用的空间是8。假如在32位环境中运行,结果将变成4。因为32位环境下地址站用4个字节的内存空间。

其实这并不矛盾。我们可以分析一下原因:

当我们将数组名作为参数传递给另一个函数时,这时已经不是两种特殊情况之一了。函数接受的自然是首元素的地址。因此,在函数内部使用sizeof()时,计算的也是首元素的地址内存大小。

所以为了让结论更准确完善,可以这样说:

当数组名作为sizeof()的参数时,这里的数组名代表整个数组,计算的是整个数组的内存大小。前提是数组的定义与sizeof()的使用必须在同一代码语句块内。

情况二:&数组名

我们知道,&是取地址操作符,那么如果将其与数组名结合在一起会发生什么呢?

来看以下代码:

int main()
{
	int arr[10] = { 0 };
	printf("%p\n", arr);
	printf("%p\n", &arr);
	return 0;
}

 运行结果:

乍一看貌似没什么区别,但改变一下代码就可看出端倪。

 

int main()
{
	int arr[10] = { 0 };
	printf("%p\n", arr+1);
	printf("%p\n", &arr+1);
	return 0;
}

可以发现,arr+1的地址相比于arr的地址增加了4,这里其实是访问了数组中的第二个元素。然而对于&arr+1的地址,其相较于&arr的地址增加了40,正好是该数组所占的内存空间!

其实这里是因为,&arr所取出的,是整个数组的地址。其数值跟arr的地址一样,但所代表的意义却不同。arr的地址代表的是该数组首元素的地址,而&arr代表的是以首元素地址所开始的整个数组。

以上,关于数组名代表整个数组的两种特例便介绍完毕了。除以上两种情况外,所有的数组名都表示数组首元素的地址

(整理码字不易,如果这篇文章能够给您带来一些收获,希望您能给个一键三连,给小弟点个关注。您的支持将极大激励我,让我们一起进步!)

 

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值