深入CC++中指针和数组的关系

深入CC++中指针和数组的关系


2024年4月28日发(作者:)

理工

2012.05

下旬刊

深入探讨C/C++中指针和数组的关系

杨黎东

(保山学院信息学院

中图分类号:TP391文献标识码:A

摘要

指针和数组是

C

语言学习中的两个重点和难点问

程序设计中如何正确理解和使用好指针对数组的访问

本文从数组的本质和编译器实现的角度论述原理

给出了

比较全面的阐述

关键词

C

语言指针数组指针与数组

AFurtherDiscussionontheRelationshipbetweenPo-

interandArrayinC/C++//YangLidong

AbstractPointerandarrayaretwoimportantanddifficultpro-

blemsinlearningClanguage,inviewofhowtoproperlyunde-

rstandandmakegooduseofanarrayofaccessinprogramming,

thisarticledetailedintroducestheprinciplefromthenatureof

anarrayandcomplier.

KeywordsClanguage;pointer;array;pointerandarray

Author

'

saddressSchoolofInformation,BaoshanCollege,

678000,Baoshan,Yunnan,China

1引言

在开发一个实际的应用程序过程中,会经常使用到数

组和指针。如何避免出现使用中的错误,使程序能够顺利地

通过编译并得到正确的运行结果,是对编程人员的基本要

求。

2指针和数组的的概念

2.1指针的概念

实体的地址也称指针

[1]

。指针不能用一般的变量存储,

需要用一种特殊的变量来存储,这种特殊的变量就是指针

变量。

我们知道,定义变量必须使用数据类型,定义指针变量

使用的就是指针数据类型,如int*、int**、char*、char**、int(*)

[4]

int(*)()等。定义的指针变量用于指向对应的实体。简单地说,

指针变量只能存储同类型实体的地址,通过指针变量访问

实体。

指针变量为什么要有类型呢?这是因为为了能正确地

通过指针变量访问数据,指针变量中仅存放实体的首地址

是不够的,还必须知道该实体占多少内存以及数据是如何

组织的,这些信息包含在数据类型之中,因此定义了正确的

指针类型,就能正确地访问实体的数据。如通过字符型指针

访问内存区域时,每次读写一个字节,通过整型指针访问内

86

云南·保山678000)

文章编号:1672-7894(2012)15-0086-02

存区域时,每次读写4个字节。

2.2数组的本质

[2]

数组是相同类型数据的有序集合,其所有元素在内存

中都是连续字节存放的,也就是说保存在一大块连续的内

存区中。当你使用“[]”来引用数组元素的时候,编译器必须

把它转换为同类型的指针表示形式,然后再行编译。例:

a[3]=100;//转换为*(a+3)=100;

cout<

数组名字本身就是一个指针,是一个指针常量。即a等

价于int*consta,因此你不能试图修改数组名的值。数组名

的值就是数组第一个元素的内存单元首地址,即a=&a[0]。

表达式中的数组名总是被编译器解析为指针,下标总是和

指针的偏移量相同。C语言中将数组的下标改写成指针偏移

量的主要原因在于指针和偏移量是底层硬件所使用的基本

类型。如a[i]中的i总被编译器解析为偏移量,所以a[i]总是

被改写成*(a+i)的形式,a是指向数组第一个元素的指针,加

上偏移量i,表示该指针向后移i个步长,然后取a+i所在单

元的内容。这样,我们就可以通过同类型的指针迭代

(++/--)来遍历整个数组。

3二维数组与指针

C语言规定

[3]

:任何维数的数组都可以看做是由比它少

一维的数组为元素组成的一维数组。例如inta[3][4]={

{1,2,3,4},{5,6,7,8},{9,10,11,12}};首先,C语言把a看做一维数

组,它有三个元素a[0]、a[1]、a[2],每一个元素代表一行;其次,

a[0]、a[1]、a[2]分别是三个一维数组,一维数组a[0]包含a[0]

[0]、a[0][1]、a[0][2]、a[0][3]四个元素;一维数组a[1]包含a[1][0]、

a[1][1]、a[1][2]、a[1][3]四个元素;一维数组a[2]包含a[2][0]、a[2]

[1]、a[2][2]、a[2][3]四个元素。换句话说,a是一个二维数组的

数组名,a数组包含3个元素:a[0]、a[1]、a[2],而每个元素又

是一个一维数组(由4个元素组成的一维数组)。可以认为

二维数组是“由一维数组为元素组成的一维数组”,即数组a

是由3个一维数组所组成,是“数组的数组”。

a是a[0]的地址,a[0]是a[0][0]的地址,*a等价于a[0],**a

等价于*a[0]等价于a[0][0]。a[0]+1也就是*a+1,是a[0][1]的

地址,所以*(a[0]+1)或*(*a+1)等价于a[0][1]……

a+1是a[1]的地址,a[1]是a[1][0]的地址,*(a+1)等价于a

[1],**(a+1)等价于*a[1]等价于a[1][0]。a[1]+1也就是*a+1是

2012.05

下旬刊

a[0][1]的地址,所以*(a[1]+1)或*(*(a+1)+1)等价于a[0]

[1]……

*(*(a+i)+j)或*(a[i]+j)等价于a[i][j]。

1245008

1

a[0]

a

a[0]

1245012

2

a[0]+1

1245016

3

a[0]+2

1245020

4

a[0]+3

1245024

5

a[1]

a+1

a[1]

1245028

6

a[1]+1

1245032

7

a[1]+2

1245036

8

a[1]+3

1245040

9

a[2]

10

a+2

a[2]

1245044

←a[2]+1

1245048

11

←a[2]+2

1245052

12

←a[2]+3

二维数组数据结构示意图

4指针数组与多级指针

[5]

由指向同一数据类型数据的指针为元素组成的数组叫

指针数组

[4]

。一维指针数组的定义形式为:

类型*数组名[元素个数];

例如,int*num[5];定义了一维指针数组num,它有5个

元素num[0]、num[1]、num[2]、num[3]、num[4],每个元素都是指

向整型单元的指针变量。

【例】指针数组和多级指针的用法。

#include

voidmain()

{

char*c[]={“enter-”,”newgang”,”point”,”firwu”};

char**cp[]={c+3,c+2,c+1,c};

char***cpp=cp;

printf(“n%s”,**++cpp);//第一个printf()语句

printf(“%s”,*--*++cpp+5);//第二个printf()语句

printf(“%s”,*cpp[-2]+3);//第三个printf()语句

printf(“%s”,cpp[-1][-1]+3);//第四个printf()语句

}

程序运行结果:

point-wugang

分析:本程序开始通过初始化,使得指针数组c中的c

[0]、c[1]、c[2]、c[3]分别指向字符串”enter-”,”newgang”,”point”

和”firwu”。cp也是一个指针数组,每个指针指向下层的“指

针元素”,即它们是指向“指向字符串的指针”的指针。通过

初始化使得cp[0]、cp[1]、cp[2]、cp[3]分别指向c指针数组中

的c[3]、c[2]、c[1]和c[0]。cpp是个三能指针,通过初始化使其

指向cp指针数组的第0个元素。此时的数据结构的存储布

局如下图所示。

理工

cpp

cp

c

enter-0

newgang0

point0

firwu0

数据结构示意图

当程序执行到第一个printf()语句时,**++cpp指向其一

个特定的地址,按优先级规则,表达式的执行顺序应该是*

(*(++cpp))。cpp开始指向cp[0],执行前置加1,使得cpp指向

cp[1],*cp[1]则指向c[2],*c[2]指向point字符串的首字符p;

故将point字符串输出。执行程序中的第二个printf()语句时,

由于执行第一个printf()语句时cpp已指向cp[1],

*--*++cpp+5表达式按其优先规则应该是(*(--(*(++cpp))))

+5,++cpp使cpp由原指向cp[1]变为指向cp[2],--(cp[2])使

其原来指向的c[1]转变为c[0],输出内容是c[0]所指向的地

址再加上5所指向的子字符串,即输出“-”。当执行程序中

的第三个printf()语句时,其表达式是*cpp[-2]+3,由于第二

个和第三个printf()语句的前置加1操作使得cpp已指向了

cp[2],此时用下标表示cpp[-2]相当于cp[0],而cp[0]指向的

是c[3],输出内容是c[3]所指向的地址再加上3所指向的子

字符串“wu”。当执行程序中的第四个printf()语句时,cpp[-1]

[-1]+3指出了输出内容的确切地址。由于cpp指向cp[2],所

以-1则使cpp指向cp[1],cp[1]指向c[2],再执行-1则使cp

[1]由指向c[2]变为指向c[1],此时c[1]指向的地址再加3,指向

字符串“newgang”的第三个字符开始的子字符串,就是输出

子字符串“gang”。

5结语

通过以上分析和实例,我们可以弄清指针和数组的内在

联系和用法,这里主要讲述了数组和指针类型的关系,通过

对它们之间关系的了解可以更加深入地把握数组和指针特

性的知识,从而避免程序设计中因使用不当而出现的各种

错误。

★基金项目:保山学院校级自然科学研究基金项目(项

目编号:09B003JK)

参考文献

[1]谭浩强.C程序设计[M].第4版.北京:清华大学出版社,2010:220-

230.

[2]林锐,韩永泉.高质量程序设计指南-C++/C语言[M].第2版.北

京:电子工业出版社,2003:166.

[3](美)HerbertSchildt.C语言大全[M].第1版.郭兴社,戴建鹏,编译.

1990:131-137.

[4]赵家刚,李俊荻.C语言程序设计[M].第1版.西安:西安交通大学

出版社,2010:140.

[5]赵海廷.汉化TurboC程序设计[M].第1版.1997:204-206.

编辑胡俊龙

87


发布者:admin,转转请注明出处:http://www.yc00.com/web/1714259449a2412125.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信