C语言——深入理解指针(2)(数组与指针)

数组名的理解

之前我们在使用指针访问数组内容时,有这样的代码:

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

这里我们使用&arr[0]的方式拿到了数组第一个元素的地址,但是其实数组名本来就是地址,而且是数组首元素的地址。
我们来做个测试,看数组名到底是不是首元素的地址:
在这里插入图片描述
从打印出来的值来看,它们确实是一样的,所以数组名确实是首元素的地址。
那么数组名是首元素地址的话,我们去求地址长度,在32位平台下应该为4个字节(地址的长度与多少位的平台有关)
我们用sizeof计算下地址长度是多少:
在这里插入图片描述
这是为什么呢?
数组名就是数组首元素(第一个元素)的地址,但是有两个例外:

  • sizeof(数组名),sizeof中单独放数组名时,这里的数组名表示整个数组,不是首元素的地址,此时计算的是这整个数组的大小,单位是字节。
  • &数组名,这里的数组名表示整个数组,取出的是整个数组的地址(整个数组的地址和数组首元素的地址是有区别的)在这里插入图片描述
    从值的角度来看的话,取整个数组的地址与取首元素的地址打印出来的值一模一样。
    这是因为无论是取首元素地址,还是取整个数组的地址,它们的值都是从首元素的地址开始的。
    但是我们平时写代码的时候要知道,数组名前+取地址符号是取整个数组的地址。
    如果我们想看看它们的区别还是可以看到的,我们给首元素的地址、整个数组分别都+1:
    在这里插入图片描述
    在这里插入图片描述
    我们发现,前两个地址+1都只跳过了一个整形的大小,而第三个地址+1却跳过了一个数组的大小(40个字节)
    所以我们将三个地址打印出来只能看到打印出来的值是一样的,但是类型绝对是不同的,因为int*类型+1跳过的应该是一个整形,而不是40个字节。

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


使用指针访问数组

有了前面知识的支持,再结合数组的特点,我们就可以很方便的使用指针访问数组了。
为什么在访问数组的时候可以使用指针呢?
1.因为数组在内存中是连续存放的,只要是连续存放的,只要找到第一个,就可以顺藤摸瓜找到其他的了。
2.指针±整数的运算,方便我们获得每一个元素的地址

接下来我们写个代码,实现用指针访问数组,给数组的每个元素输入值,再输出值。在这里插入图片描述
注意:
数组就是数组,是一块连续的空间(数组的大小与元素个数和元素类型都有关系)
而指针(变量)就是指针(变量),是一个变量(通常是4/8个字节)
那么它俩之间的联系是什么呢?
数组名是地址,是首元素的地址,可以使用指针来访问数组

拓展:
我们知道arr[i]*(arr+i)这两种写法是完全等价的,并且*(arr+i)里面的式子是加法,加法是支持交换律的。所以arr[i]==*(arr+i)==*(i+arr)
我们代入代码中看会不会错:
在这里插入图片描述
结果也是正确的。
既然这三个等价:arr[i]==*(arr+i)==*(i+arr)
*(arr+i)可以写成arr[i],那么*(i+arr)可不可以写成i[arr]呢?
我们带入代码试试:
在这里插入图片描述
我们发现即使是这样程序也没有问题。那么这说明了什么呢?
我们知道[]是个下标引用操作符,既然加号操作符+可以实现:1+2可以写成2+1;那么,arr[i]也就可以写成i[arr]
提示:这种方式虽然可行,但是不推荐。
因为这样写不利于阅读代码。


一维数组传参的本质

数组我们学过,数组是可以传递给函数的,现在我们讨论一下数组传参的本质。
首先从第一个问题开始:
写个函数实现数组元素的打印,我们之前都是在函数外部计算数组元素的个数:
在这里插入图片描述
那我们可以只把数组传给函数,少传一个参数。然后在函数内部求数组的元素个数再打印数组嘛?在这里插入图片描述
此时我们这样写却出现错误,数组里的元素只打印了一个,这是为什么呢?我们进行调试:

  • 按F11开始调试,创建数组执行完后打开监视,查看创建的数组有没有问题:
    在这里插入图片描述
  • 发现创建数组没有问题后按F11进入函数内,在监视里输入arr,10查看数组传参有没有问题:在这里插入图片描述
    此时数组的传参也没有问题ÿ
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值