首页 百科知识 指针与数组

指针与数组

时间:2023-10-16 百科知识 版权反馈
【摘要】:指针用于存储地址,它和数组名紧密地联系在一起。因为p是指针变量,变量的值是可以改变的,p的初值是grade数组的首地址,p=p+3表示p指向数组元素grade[3],此时访问*p就相当于访问数组元素grade[3]的值。cnt函数头行使用字符指针*p接收字符数组s的首地址,函数cnt中使用代码p++改变指针p的指向,使用*p访问字符数组元素。

6.3 指针与数组

指针用于存储地址,它和数组名紧密地联系在一起。图6-9就显示了一个数组名称为grade的一维整型数组,它包含5个数据,每个整型元素占用4个字节,内存中存储形式如图所示。

img237

图6-9 数组在内存中存储形式

访问数组元素,可以使用下标来实现,比如要访问数组元素grade[3],在之前的章节里详细的讲解过,但是那时使用的方法其实隐藏了数组每一个元素的地址。根据之前讲过的地址的概念,结合数组在内存中占用一块连续的存储区域的特点可知,如果知道了数组某个元素的地址,改变偏移量,就可以得到数组其他元素的地址,进而访问该元素值。

以grade数组为例,数组元素grade[0]的地址可以通过取地址运算符“&”获得,即&grade[0],数组中grade[3]元素的地址计算方法如下所示:

&grade[3]=&grade[0]+3*4;

如果有指针变量p指向数组元素grade[0],根据指针变量自运算规则,使用指针访问grade[3]的代码如下所示:

img238

指针变量p首先指向数组元素grade[0],正向偏移3个存储单元后,p指向数组元素grade[3]。

【例6.6】分别使用下标和指针访问数组元素。

代码如下:

img239

运行结果如图6-10所示。

img240

图6-10

分析:

表达式*(p+i)表达式的含义是,指针从数组首地址偏移i个存储单元(由于int数据占4个字节,所以每次偏移4*i个字节),访问该单元中的数据值。

需要注意的是*(p+i)表达式中的括号是必须有的,不能省略。如果遗漏了小括号,将变成这样的表达式*p+i,它的含义是对p所指向的存储单元的数值加i,而不是p+i所指向存储单元的值。

6.3.1 数组名作为指针

每个创建的一维数组,数组名就成为编译器为这个数组所创建的指针常量名称,它存储的是数组第一个元素的地址,也就是数组首地址。这样,就又多了一种获取数组元素地址的手段。

例如:

img241

分析下面的代码,看看错了吗?

grade=grade+3;

错误的。原因是,grade是数组名,它是指针常量,常量是不能够赋值的。

再分析下面的代码,是否有问题?

p=grade;

p=p+3;

正确的。因为p是指针变量,变量的值是可以改变的,p的初值是grade数组的首地址,p=p+3表示p指向数组元素grade[3],此时访问*p就相当于访问数组元素grade[3]的值。

【例6.7】有n个整数,存储在数组array中,使其前面各数顺序向后移m个位置,最后m个数变成最前面的m个数,并输出。

例如:输入数据“1 2 3 4 5 6”,输出数据“4 5 6 1 2 3”。

代码如下:

img242

img243

运行结果如图6-11所示。

img244

图6-11

分析:

代码arrayend=*(array+n-1)表示存储数组最后一个元素的值,因为循环后移数组元素将覆盖原位置数据,导致最后一个数据元素丢失,故应先将其保存。

6.3.2 指针与多维数组

数组在内存中占用连续的存储区域,以二维数组array[2][3]为例,6个数组元素数在内存储中存储形式如图6-12所示。

img245

图6-12 二维数组在内存中存储形式

下面逐步分级二维数组和指针的关系:

第一步,写出最容易理解的形式:

img246

【例6.8】使用三种不同的方法访问二维数组。

代码如下:

img247

img248

运行结果如图6-13所示。

img249

图6-13

分析:

第一个for循环使用下标形式直接访问了二维数组元素;第二个for循环使用了数组名间接访问了二维数组元素;第三个for循环使用指针访问了二维数组元素,因为p是一个指针变量,它的初值是数组的首地址,通过改变偏移量,使指针p指向不同地址,实现了输出数组元素的目的。

首先指针p指向数组array的首地址,就是array[0][0]的地址,因为数组array是由2行3列组成的,所以3*i+j表示第i行第j列元素对应的偏移量;*(p+3*i+j)表示的就是数组元素array[i][j]。

【例6.9】统计在array字符串中从a到z的26个小写字母各自出现的次数。

例如:输入字符串"abcdefgabcdeabc",输出的结果应该是“33322110000000000000000000”。

代码如下:

img250

运行结果如图6-14所示。

图6-14

分析:

cnt函数头行使用字符指针*p接收字符数组s的首地址,函数cnt中使用代码p++改变指针p的指向,使用*p访问字符数组元素。题目很巧妙地使用差值*p-ˊaˊ作为数组元素的下标,代码arr[*p-ˊaˊ]++统计每个小写字母的个数。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈