目录
我们知道,数组名在绝大多数情况下表示的是数组首元素的地址。数组,无论是一维数组还是二维数组,其在内存中都是连续存放的。因此,通过访问该数组的首元素地址就可以访问数组的全部元素。
可是,在实际运用中,有两种特殊情况,数组名并不代表首元素的地址,而是代表整个数组。接下来让我们一起解析一下。
情况一:数组名作为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代表的是以首元素地址所开始的整个数组。
以上,关于数组名代表整个数组的两种特例便介绍完毕了。除以上两种情况外,所有的数组名都表示数组首元素的地址
(整理码字不易,如果这篇文章能够给您带来一些收获,希望您能给个一键三连,给小弟点个关注。您的支持将极大激励我,让我们一起进步!)