翻过指针这座山(2)!

在上一篇博客中主要初级的介绍了一点指针的内容,这次我们接着来看两个概念:
指针数组数组指针
指针数组是什么呢?而数组指针又是什么呢?在这里我们进行一个简单的区分:
指针数组是一个数组,这里数组里面存放着指针,可以指向不同的地址进行访问。
数组指针是一个指针,这个指针能够指向数组,指针指向数组的地址,在一维数组中其实指向的就是数组首元素的地址,而在二维数组中就是指向的是二维数组第一行的地址,二维数组其实是特殊的一维数组,但在这里,虽然数组的地址和数组首元素的地址相等,但是所表示的意义不同,下面给个代码说明:

#include<stdio.h>
intmain()
{
intarr[10]={0};
printf("arr=%p\n",arr);
printf("&arr=%p\n",&arr);
printf("arr+1=%p\n",arr+1);
printf("&arr+1=%p\n",&arr+1);
return0;

运行结果如下:
在这里插入图片描述
根据上面的代码我们发现,其实&arr和arr,虽然值是一样的,但是意义应该不一样的。
实际上: &arr 表示的是数组的地址,而不是数组首元素的地址。(细细体会一下)
数组的地址+1,跳过整个数组的大小,所以arr+1相对于&arr的差值是40

指针数组和数组指针的内存布局
数组指针和指针数组的表示:
指针数组的表示为 intp1[10];在arr的这个空间为5的数组中,存放着5个int的指针。
数组指针的表示为int(p2)[10]:因为的优先级低于[],所以加括号。首先加了括号就代表这是一个指针,指向arr[5]。给个图说明一下:
在这里插入图片描述

从上面这个图片能很清楚的看到这两者的区别。
多维数组与多级指针
在这里先说下二维数组的布局
假想的二维数组布局:
在这里插入图片描述
实际上内存不是表状的,而是线性的。既然内存是线性的,那二维数组在内存里面肯定也是线性存储的。实际上其内存布局如下图:
在这里插入图片描述
以数组下标的方式来访问其中的某个元素:a[i][j]。编译器总是将二维数组看成是一个
一维数组,而一维数组的每一个元素又都是一个数组
。a[3]这个一维数组的三个元素分别为:
a[0],a[1],a[2]。每个元素的大小为 sizeof(a[0]),即 sizof(char)4。由此可以计算出 a[0],a[1],a[2]
三个元素的首地址分别为& a[0],& a[0]+ 1
sizof(char)4,& a[0]+ 2sizof(char)4。亦即 a[i]
的首地址为& a[0]+ i
sizof(char)4。这时侯再考虑 a[i]里面的内容。就本例而言,a[i]内有 4 个 char 类型的元素,其每个元素的首地址分别为&a[i],&a[i]+1sizof(char),
&a[i]+2sizof(char),&a[i]+3sizof(char),即 a[i][j]的首地址为&a[i]+jsizof(char)。再把&a[i]
的值用 a 表示,得到 a[i][j]元素的首地址为:a+ i
sizof(char)4+ jsizof(char)。同样,可以换
算成以指针的形式表示:((a+i)+j)。

二级指针的内存布局:
二级指针是经常用到的,尤其与二维数组在一起的时候更是令人迷糊。例如:
char **p;
定义了一个二级指针变量 p。p 是一个指针变量,毫无疑问在 32 位系统下占 4 个 byte。
它与一级指针不同的是,一级指针保存的是数据的地址,二级指针保存的是一级指针的地
址。给图说明一下:
在这里插入图片描述
任何指针变量都可以被初始化为 NULL),二级指针也不例外。也就是说把指针指向数组的零地址。联想到前面我们把尺子比作内存,如果把内存初始化为 NULL,就相当于把指针指向尺子上 0 毫米处,这时候指针没有任何内存可用。
当我们真正需要使用 p 的时候,就必须把一个一级指针的地址保存到 p 中,所以 B)的
赋值方式也是正确的。
给 p 赋值没有问题,但怎么使用 p 呢?这就需要我们前面多次提到的钥匙(“”)。
第一步:根据 p 这个变量,取出它里面存的地址。
第二步:找到这个地址所在的内存。
第三步:用钥匙打开这块内存,取出它里面的地址,p 的值。
第四步:找到第二次取出的这个地址。
第五步:用钥匙打开这块内存,取出它里面的内容,这就是我们真正的数据,**p 的值。
我们在这里用了两次钥匙(“
”)才最终取出了真正的数据。也就是说要取出二级指针
所真正指向的数据,需要使用两次两次钥匙(“
”)。

以上就是关于我看过资料对于指针和数组的一点小理解,这个指针感觉东西太多,我还会发几篇这个系列博客,希望各位大佬多多指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值