一.使用指针访问数组
关于数组,我在上次的博客中也提到了一些比较重要的知识点。首先就是数组名,数组名只有在两种情况下代表的是整个数组的地址,一个是在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*。
当然了大家也可以发挥想像,三级指针四级指针等等。
感谢观看,如有错误还请指正。
标签:10,int,地址,深入,数组,sizeof,指针 From: https://blog.csdn.net/2301_81699364/article/details/136662179