指针第二章、指针与数组

本文详细解释了数组名作为地址的概念,指针如何访问数组元素,以及一维数组传参的实质。同时介绍了指针数组的概念,指出它是存放地址的数组,可用于模拟二维数组。
摘要由CSDN通过智能技术生成

上一章中我们学习了传址调用和传值调用,那么通过本章的学习我们将会对指针的使用有进一步的认识。

一、数组名的理解

 在指针的学习过程中,我们会遇到如下代码:

int arr[10] = {1,2,3,4,5,6,7,8,9,10}
int *p = &arr[0]

但是实际上,数组名本身就是地址,而且是数组首元素的地址,我们可以来验证一下:

如图所示,&arr[0]和arr最后的结果是一样的,都是同样的地址,由此可见 数组名本身就是地址,而且是数组首元素的地址。

那么这个时候或许就会有疑问,如果是首元素的地址,那么下面的代码怎么理解呢??

sizeof用于查看数组的大小,如果是首元素的地址, sizeof应该得到的结果是4或者8才对,为什么会得到40呢?

那是因为数组名有两个例外:

(1) sizeof(数组名),sizeof单独放一个数组名,这里的数组名表示整个数组,代表的是整个数组的大小,单位是字节

(2) &数组名,这里的数组名表示整个数组,取得是整个数组的地址

除此之外,其他任何地方的数组名都表示首元素的地址。 

第二个和第三个是一样的,但是他们两个表示的内容是不一样的,第一个和第二个表示首元素的地址,但是第三个表示整个数组的地址。但是第三个和第二个的值为什么是一样的呢?那是因为整个数组的地址需要首元素来表示。

 那么我们可以通过下面的代码来加深理解:

众所周知,一个int类型占四个字节,那么首元素加一,就是跳过四个字节,因此&arr[0]+1和arr+1都跳过了四个字节。

那么 &arr+1是怎么回事呢?我们首先要理解,在内存中地址的存储由十六进制来完成,所以我们得到的结果都是十六进制表示。其中00AFFD58 − 00AFFD30 = 28,28转换为十进制数就是40(8*16^0+2*16^1=40),所以跳过了40个字节。

二、指针访问数组

数组在内存中连续存放,通过指针+-整数就可以得到每个数组元素:

 如图,在printf中通过对指针的解引用完成对数组的打印。p存储地址,由于p先指向了首地址,通过i依次访问数组的每一个元素。

数组名arr和p是等价的,我们可以通过arr[i]访问数组的元素,那么p[i]是否也可以呢??

我们把p[i]换成arr[i],所以本质上p[i]和arr[i]是等价的,那么三次打印结果均相同,所以arr[i]、p[i]和*(p+i)都是等价的。

三、一维数组传参的本质 

我们在创建函数时总是会把数组的大小传给函数而不是在函数内部求数组的大小,那么我们是否可以在函数内部计算数组的大小呢?

sz和sz2的值并不相同,这就要探究数组传参的本质:

         数组名是首元素的地址,所以我们传给test数组名就相当于传了首元素的地址给了函数。因此我们在函数内部计算大小只能得到第一个元素地址的大小。由于我们传的是一个指针,所以我们无法在函数内部计算数组的大小。

那么既然传递的是指针,我们就可以换一种写法:

所以形参的部分可以写成数组的形式,也可以写成指针的形式。

四、指针数组 

指针数组是指针还是数组呢??

整数数组是存放整数的数组,那么指针数组就是存放指针的数组,所以指针数组其实是数组。

指针数组的每个元素都是存放地址的:

 

指针数组的每个元素都是地址,指向一块区域。 

指针数组也可以模拟二维数组,这样也可以加深理解:

 

  • 19
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值