是
我们在c语言的学习中,常常会遇到需要用到数组作为函数参数的情况,那么数组的传参是如何实现的呢?
我们以冒泡排序为例:
include<stdio.h>
void maopao(int sz[],int length)
{
for (int i = 0;i < length - 1; i++)
{
for (int j = 0; j < length - i - 1; j++)
{
if (sz[j] > sz[j + 1])
{
int temp = sz[j];
sz[j] = sz[j + 1];
sz[j + 1] = temp;
}
}
}
for (int i = 0; i < length; i++)
{
printf("%d",sz[i]);//0,1,2,3,4,5,6,7,8,9
}
}
int main()
{
int sz[10] = {9,8,7,6,5,4,3,2,1,0};
int length = sizeof(sz) / sizeof(sz[0]);
maopao(sz,length);
return 0;
}
可以看到,调用函数时我输入的是数组名,函数却得到了数组的所有数据,因此可以确定数组名与数组存在某种联系,得到这一信息后我们可以大胆假设,数组名就是数组的地址,然后加以验证
#include<stdio.h>
int main() {
int sz[10] = { 9,8,7,6,5,4,3,2,1,0 };
for (int i = 0; i < 10; i++) {
printf("%p\n", &sz[i]);
}
printf("----------------------------------\n");
printf("%p", &sz);
return 0;
}
/*程序执行的结果如下:
0000009BEE6FFCA8
0000009BEE6FFCAC
0000009BEE6FFCB0
0000009BEE6FFCB4
0000009BEE6FFCB8
0000009BEE6FFCBC
0000009BEE6FFCC0
0000009BEE6FFCC4
0000009BEE6FFCC8
0000009BEE6FFCCC
-----------------
0000009BEE6FFCA8
*/
如上将数组每一个元素的地址和数组名地址都打印,从打印的结果发现数组名的地址与数组第一个元素的地址相同,假设就又进了一步,数组名可能是数组首元素的地址,此时又出现了一个问题,数组名的地址与数组首元素的地址有什么异同,我们深入这一问题验证
#include<stdio.h>
int main() {
int sz[10] = { 9,8,7,6,5,4,3,2,1,0 };
printf("%p\n", &sz[0]);
printf("%p\n", &sz[0] + 1);
printf("%p\n", &sz[1]);
printf("-----------------\n");
printf("%p\n", &sz);
printf("%p\n", &sz + 1);
return 0;
}
/*
000000B219CFFBD8
000000B219CFFBDC
000000B219CFFBDC
-----------------
000000B219CFFBD8
000000B219CFFC00
*/
可以看到,将数组首元素的地址与数组名地址分别+1后出现了不同的变化,说明了数组首元素的地址不是数组名的地址,那么数组名的地址到底意味着什么呢?结合结果分析数组首元素的地址+1后因为是int类型所以增加了4个字节,变成了下一个数组元素的地址,回过来看数组名的地址,在c语言中地址是以16进制表示的,将前后的结果转换为十进制后发现,数组名的地址+1后增加了40个字节,直接就跳过了整个数组了,这说明数组名变现出来的是数组首元素的地址,但其代表的是整个数组的地址。
由此可以得出结论:数组名就是数组首元素的地址,取数组名的地址时得到的是整个数组的地址,数组名一般代表的都是数组首元素的地址,但存在两种情况:
1.取数组名的地址时,取出的是整个数组的地址
2.用sizeof计算大小时,数组名代表的是整个数组,即计算数组长度常用的方法sizeof(sz)/sizeof(sz[0]);