文章目录
1.数组名与地址
有这么一个数组,数组名为 arr
int arr[10] = {1,2,3,4,5,6,7,8,9}
int *p = &arr[0]
在这里 &arr[0] 指的是首元素地址,其实本质上数组名就代表的是数组首元素地址
接下来我们将对以下几个名字进行区分
1.arr
2.sizeof(arr)
3.&arr
1.1 arr
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("&arr[0] = %p\n", &arr[0]);
printf("arr = %p\n", arr);
return 0;
}
根据以上保留取地址符&和只用数组名,打印对应的地址可以发现
两个的地址都相同,这就说明了 &arr[0] = arr,即数组名就是首元素地址
1.2 sizeof(arr)
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("%d\n", sizeof(arr));
return 0;
}
这里关键字 sizeof 计算 arr 的大小,你可能会觉得应该输出首元素的大小?
不,这里的 arr 不代表首元素大小,而是表示整个数组,计算整个数组的大小,单位是字节
1.3 &arr
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("%p\n", &arr);
printf("%p\n", &arr+1);
return 0;
}
打印 &arr 和 &arr+1 地址,假设他是跳过一个字节的地址
很显然,根据代码结果,两段代码地址相差40,那么假设就是错的,所以 &arr 表示的是整个数组的大小
总结:只有 &arr 和 sizeof(arr) 有特殊含义,其他情况下的数组名都代表数组首元素地址
2.指针访问数组
#include <stdio.h>
int main()
{
int arr[10] = {0};
//输⼊
int i = 0;
int sz = sizeof(arr)/sizeof(arr[0]);
//输⼊
int* p = arr;
for(i=0; i<sz; i++)
{
scanf("%d", p+i);
//scanf("%d", arr+i);//也可以这样写
}
//输出
for(i=0; i<sz; i++)
{
printf("%d ", p[i]);
}
return 0;
}
使用指针访问数组在一些环境下,会更接近本质,更加简洁易懂
将 *(p+i) 换成 p[i] 也是能够正常打印的
在这里解引用操作符和下标引用符产生的效果相同
本质上p[i] 是等价于 *(p+i),数组元素的访问在编译器处理的时候,也是转换成首元素的地址+偏移
量求出元素的地址,然后解引用来访问的
3.一维数组传参本质
在前面学习的函数篇章中,数组可以传递给自定义函数,那么数组传递的本质是什么呢?
#include <stdio.h>
void test(int arr[])
{
int sz2 = sizeof(arr)/sizeof(arr[0]);
printf("sz2 = %d\n", sz2);
}
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int sz1 = sizeof(arr)/sizeof(arr[0]);
printf("sz1 = %d\n", sz1);
test(arr);
return 0;
}
通过以上代码调试后可以发现,sz1 = 10,sz2 = 1,同样的算法应该 sz1 = sz2 =10 ,但穿过去的形参根据结果 sizeof(arr) 只计算出一个元素的大小,前面我们提到 arr 表示首元素的地址,那么在数组传参的时候,传递的是数组名,也就是数组传参的时候传递的是首元素的地址
所以函数的形参应该用指针变量来接收一个地址,这也证实了数组传参的本质是传递首元素地址
形参部分既可以写成 int * arr 的指针形式,也可以写成 arr[ ] 的数组形式
4.指针数组
什么是数组指针?什么是指针数组?这里我们重点介绍一下指针数组
指针数组是一个数组,比如整型数组存放的数组,字符数组存放的是字符,那么指针数组存放的就是指针
int* arr[5] = 5个int*
每一个数组里的指针都指向一个地址
5.二级指针
正常的一个常见的指针是一级指针,那么在一个指针里面再嵌套一个指针就是二级指针
是变量就有地址,指针变量也不例外,比如把指针变量的地址需要存放在另一个指针变量里
#include <stdio.h>
int main()
{
int i = 5;
int * pi = &i;
int ** pii = π
return 0;
}
*pii 通过对 pii 中的地址进行解引用,这样找到的是 pi , *pii 其实访问的就是 pi
**pii 先通过 *pii 找到 pi ,然后对 pi 进行解引用操作: *pi ,那找到的是 i
博主最近在准备蓝桥杯的校内比赛,更新可能会有所减缓,大家多多谅解!
标签:arr,int,vlog.12,C语言,地址,数组,sizeof,500,指针 From: https://blog.csdn.net/Zero_VPN/article/details/143359346