深入了解指针(2)【指针与数组】【二级指针】

一.使用指针访问数组

关于数组,我在上次的博客中也提到了一些比较重要的知识点。首先就是数组名,数组名只有在两种情况下代表的是整个数组的地址,一个是在sizeof里面,一个是用&符号。

那么为什么我们可以用指针来访问数组呢?因为数组在内存中是连续存放的,只要我们找到第一个地址,那么后面的地址不也是手到擒来的吗。

我们先想一个简单的代码,先假设有一个数组a[10],这个数组的元素让我们去输入,而我想要把这十个元素按照顺序依次输入,是不是一下就可以想到咱们可以用for循环,创建一个变量i,依次递增很轻松就能写出这样一个代码。

#include <stdio.h>
int main()
{
	int a[10] = { 0 };
	int sz = sizeof(a) / sizeof(a[0]);
	for (int i = 0; i < sz; i++)
	{
		scanf("%d", &a[i]);
	}
	return 0;
}

但我如果想要用指针写呢?很简单,咱们只需要加一个整型指针的变量就行了。

#include <stdio.h>
int main()
{
	int a[10] = { 0 };
	int sz = sizeof(a) / sizeof(a[0]);
	int* p = a;
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		scanf("%d", p + i);
	}
	return 0;
}

这里for循环里的p+i的意思其实就是a[i],p指针指向的就是数组的第一个元素的地址,而加i就是每一次往后面移动几位。访问的第几个位置,如图

依次加i就能成功访问到数组的各个位置,达到输入输出的目的。这里我说一个比较有意思的东西。大家知道,表示数组里的某一个元素咱们可以直接写成a[i],当然用指针也是可以,*(a+i)或者*(i+a)。那么大家可以想一下i[a]可以吗?这里我是把i和a反过来了。用代码来看一下结果。

当然也是成功运行打印出来了结果,那么为什么i[a]可以运行出来结果呢?这里我额外说一个东西就是[],[]是一个下标引用操作符,当我们把数组写成a[i]时,就相当于是*(a+i),而写成i[a]时,就相当于是*(i+a),这只是个加法调换了一下位置而已。但是这种方法可行但是不太推荐。大家了解一下就行。

二.一维数组传参的本质

我们知道,数组是可以传递给函数的,我们可以探索一下数组传参的本质。先看一个代码:

这里我传递的是一个数组,但是只打印出来了一个0;肯定是有一个地方不对。事实上,在我们的Print函数里面的sz大小其实是1,因为我们在主函数里面给Print传递参数的时候,给它的是arr,arr是个数组名啊,除了sizeof和&其他的情况代表的都只是数组首元素的地址,所以这里就相当于只传递了一个地址,1除以1sz当然就等于1了。

在我们初学数组传参的时候,在语法的层次上讲,我们会把参数写成数组的形式就像是上面的代码int arr[10],这样我们可以更好的理解,当然这样是肯定可以的,但是其本质上还是地址,相当于我们放在这里的就只是int *arr,本质上还是指针变量。

有两点需要说一下:1.数组传参的本质是传递了数组首元素的地址,所以形参访问的数组和实参的数组是同一个数组。2.形参的数组是不会单独再创建数组空间的,所以形参的数组是可以省略掉数组大小的(简单的说,在形参里的a[10]可以写成a[])。

总结:一维数组传参,形参的部分可以写成数组的形式,也可以写成指针的形式。

三.二级指针

其实我们常用的一些指针是一级指针,比如

int main()
{
	int a = 10;
	int* p = &a;
	return 0;
}

在这里的p就是一级指针,存储的是a的地址。我们假设a的地址为0x0012ff40,此时的p里面存储的就是0x0012ff40。那么大家想,p也是一个变量啊,那么p在内存中有没有地址呢?答案是肯定有的。我再把p 的地址拿出来再赋值给一个变量pp,此时的pp就是二级指针

那么pp的类型应该就是int**,也就是int**pp=&p。那么int**我们该如何理解。

我们可以拆开理解int**,我们知道a的类型是int,p的类型是int*。

当然了大家也可以发挥想像,三级指针四级指针等等。

感谢观看,如有错误还请指正。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值