目录:
1. 数组名的理解
2. &数组名的理解
3.使用指针访问数组
4.一维数组传参的本质
1.数组名的理解
上一章我们在模拟strlen函数时,使用了数组名进行了函数的传参,那么数组名到底意味着什么呢?
#include<stdio.h>
int main()
{
int arr[5] = {1,2,3,4,5};
int *p = &arr[0];
}
当我们使用&arr[0]时,我们会将数组首元素的地址取出来
那我们将数组名的地址打印出来呢?
即使没有取出数组名的地址,系统也并没有报错,打印出来的地址还是和首元素地址一样
难到数组名就是地址吗?
没错,数组首元素的地址和数组名就是一样的,其实数组名本身就是地址,而且就是数组首元素的地址
什么?!!那arr[0],该怎么理解,地址[0]是什么鬼?
其实,arr[0]的含义是 *(arr+0) ,这样得到的数组首元素的值
结论:
数组名就是一个地址
数组名就是数组首元素(第一个元素)的地址
2.&数组名的理解
疑问时刻:
数组名是首元素的地址,那把数组名的地址取出来后,得到的是什么呢?
我们可以看到,无论是打印arr[0]的地址,还是打印arr,还是&arr的地址,它们的地址都是一样的
但其实&arr是与另外两者有区别的,&arr取出的其实是整个数组的地址,但是只是显示出数组首元素的地址
实测如下:
我们会发现,arr与arr[0],它们加1后跳过了4个字节
但是 &arr+1 后 打印出的地址跳过了20个字节,也就是整个数组的大小
其实 &arr+1后,打印出的地址跳过了一整个数组
这就是它们的区别
结论:
arr与arr[0]都是数组首元素的地址,并且它们的含义一样
但是&arr取出的是首个元素的地址
2.1数组名的两个意外(重要结论)
关于数组名使用的两个例外(其他所有数组名都为首元素地址)
1.sizeof(数组名)
当我们使用sizeof(数组名)时,这里的数组名表示整个数组,因此测量的是整个数组的字节大小
2.&数组名
这里的数组名表示整个数组,取出的是整个数组的地址
3.使用指针访问数组
既然数组名可以表示首元素地址,那么我们可不可以用数组名进行整个数组的访问呢?
其实是可以的,比如:
这样我们既可以实现输入,也可以实现输出,同时使用(p+i)可以更加的节省代码与内存空间
否则就需要定义一个新的指针变量或者重新定义指针变量的值
比如:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int arr[5] = { 0 };
int* p = arr;
for (int i = 0; i < 5; i++) {
scanf("%d",&*(p));
p++;
}
p = arr;
for (int i = 0; i < 5; i++) {
printf("%d ", *(p + i));
}
}
我们知道arr是数组首元素的地址,arr[0]可以访问数组首元素,那么把arr存放在指针变量中,可以利用这个指针变量访问到数组的元素吗?
其实是可以的,比如:
其实我们在使用数组时,arr就一直都是地址,只不过我们现在才发现
既然arr是地址,那么之前所学的访问的方式依旧成立
4.一维数组传参的本质
在上一章中,我们利用数组名进行了函数的传参
那么传过去的是什么呢?
我们可以做个代码验证一下,比如:
我们发现,利用函数将数组名传过去,用指针变量进行接受时系统并没有报错,说明得到的是一个地址,并且这个地址和我们优先进行打印的数组首元素地址一样
结论:
可见,一维数组传参本质上传递的也是地址