深入理解指针(4)(上)

3abea50b9066429d84133aad1c0112e2.png

目录:

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]时,我们会将数组首元素的地址取出来

那我们将数组名的地址打印出来呢?

c1fc8c8e984d4f2eb505ac8de97469d9.png

即使没有取出数组名的地址,系统也并没有报错,打印出来的地址还是和首元素地址一样

难到数组名就是地址吗?

没错,数组首元素的地址和数组名就是一样的,其实数组名本身就是地址,而且就是数组首元素的地址

什么?!!那arr[0],该怎么理解,地址[0]是什么鬼?

其实,arr[0]的含义是 *(arr+0) ,这样得到的数组首元素的值

结论:

数组名就是一个地址

数组名就是数组首元素(第一个元素)的地址


2.&数组名的理解

疑问时刻:

数组名是首元素的地址,那把数组名的地址取出来后,得到的是什么呢?

c89639b640044074a6f539687ee9723d.png

我们可以看到,无论是打印arr[0]的地址,还是打印arr,还是&arr的地址,它们的地址都是一样的

但其实&arr是与另外两者有区别的,&arr取出的其实是整个数组的地址,但是只是显示出数组首元素的地址

实测如下:

071bd3d366d848b5a5a8a1d05912a162.png

我们会发现,arr与arr[0],它们加1后跳过了4个字节

但是 &arr+1 后 打印出的地址跳过了20个字节,也就是整个数组的大小

其实 &arr+1后,打印出的地址跳过了一整个数组

这就是它们的区别

结论:

arr与arr[0]都是数组首元素的地址,并且它们的含义一样

但是&arr取出的是首个元素的地址


 

 

2.1数组名的两个意外(重要结论)

关于数组名使用的两个例外(其他所有数组名都为首元素地址)

1.sizeof(数组名)

当我们使用sizeof(数组名)时,这里的数组名表示整个数组,因此测量的是整个数组的字节大小

2.&数组名

这里的数组名表示整个数组,取出的是整个数组的地址


3.使用指针访问数组

既然数组名可以表示首元素地址,那么我们可不可以用数组名进行整个数组的访问呢?

其实是可以的,比如:

3e7f99e09af2412292124ceff54cd0e5.png

这样我们既可以实现输入,也可以实现输出,同时使用(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存放在指针变量中,可以利用这个指针变量访问到数组的元素吗?
其实是可以的,比如:

c174e55770ac47e680d6c28ba89a42d1.png

其实我们在使用数组时,arr就一直都是地址,只不过我们现在才发现

既然arr是地址,那么之前所学的访问的方式依旧成立


4.一维数组传参的本质

在上一章中,我们利用数组名进行了函数的传参

那么传过去的是什么呢?

我们可以做个代码验证一下,比如:

9975e369bf824b44ad60784f01574618.png

我们发现,利用函数将数组名传过去,用指针变量进行接受时系统并没有报错,说明得到的是一个地址,并且这个地址和我们优先进行打印的数组首元素地址一样

结论:

可见,一维数组传参本质上传递的也是地址


2d109cecd199439e9dedb086d751bad2.png

 

  • 27
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值