在C语言中,指针和数组有着极为密切的联系。数组处理的是一些具有相同类型的元素,指针也能做同样的工作。两者相比而言,数组表示法容易理解,适合于初学者,而指针表示法则有利于提高程序的执行效率。
一个变量有地址,一个数组包含若干元素,每个数组元素都在内存单元中占用存储单元,它们都有相应的首地址。数组名是数组的首地址(不能说是数组元素的首地址),针对同一个数组来说,它是一个常量。
所谓数组的指针,是指数组的起始地址,事实上也就是数组名。一个数组是由连续的一块内存单元组成的,数组名就是这块连续内存单元的首地址。一个数组也是由各个数组元素(下标变量)组成的,每个数组元素按其类型的不同占用不同个数的连续的内存单元,指针变量既然可以指向一般变量,当然也可以指向数组元素,数组元素的指针是数组元素的地址。一个数组元素的首地址也是指它所占用的几个内存单元的首地址。
在此只讨论一维数组的指针,若需要习多维数组的指针,可参考C语言的其他相关书籍。
提示:
①数组的指针——数组在内存中的起始地址,即数组名。
②数组元素的指针——数组元素在内存中的起始地址。
2.数组的指针表示方法
前面已经介绍过,数组名代表该数组的起始地址。那么,数组中的各个元素的地址又是如何计算和表示的呢?如果有一个数组a,其定义如下:
int a[5]={1,3,5,7,9};
数组a的元素在内存中的分配如图7-4所示。由图7-4可以看出,元素a[0]的地址是a的值(即1010),元素a[1]的地址是a+1。同理,a+i是元素a[i]的地址。值得特别注意的是,此处的a+i并非简单的在首地址a上加个数字i,编译系统计算实际地址时,a+i中的i要乘上数组元素所占的字节数,即实际地址等于a+i单个元素所占的字节数。其中,单个元素所占的字节数由数据类型决定。
例如,元素a[3]的实际首地址是a+3×2(整型数据占两个字节),最终结果为1010+3×2=1016,从图7-4看出正好是这个值。
图7-4 数组a元素在内存中的分配图
定义一个指向数组元素的指针变量的方法,与以前介绍的指针变量定义方法相同。
例如:
由于数组元素a[0]的首地址与数组的首地址a相同,因此,赋值语句p=&a[0]等效于赋值语句p=a。另外,在定义指针变量时,可以赋初值,并且指针变量定义时的基类型,要与所指向的数组的类型一致。
例如:
3.一维数组元素的引用方法
为了引用一个数组元素,可以用两种不同的方法:一种是下标法,即指出数组名和下标值,系统会找到该元素,如a[3];另一种方法是指针法,也叫地址法,就是通过给出的数组元素地址访问某一元素,例如,通过地址a+3可以找到数组元素a[3],而*(a+3)的值就是元素a[3]的值。
(1)下标法
用a[i]的形式访问数组元素。前面介绍数组时都是采用的这种方法。
【例7.6】用下标法输出数组中的全部元素。
程序如下:
(www.daowen.com)
运行结果:
(2)地址法
采用*(a+i)或*(p+i)的形式,用间接访问的方法来访问数组元素,其中a是数组名,p是指向数组a的指针变量。
【例7.7】用指针法输出数组中的全部元素。
程序如下:
运行结果:
以上两个例子的输出结果完全相同,只是引用数组元素的方法不同。下标法比较直观、易用;用指针变量引用数组元素速度较快。
4.通过指针引用数组元素
C语言规定:如果p为指向某一数组的指针变量,则p+1指向同一数组中的下一个元素。如果有语句:int array[10], *pointer=array;
则:
①pointer+i和array+i都是数组元素array[i]的地址,如图7-5所示。
②*(pointer+i)和*(array+i)就是数组元素array[i]。
③指向数组的指针变量被赋值为数组名后也可按下标法来使用。例如,array[i]等价于*(pointer+i)。
图7-5 指针引用数组元素
提示:
数组名是指针常量,始终是指向数组的首地址;而指针是一个变量,可以实现本身值的改变。如有数组a和指针变量p,则以下语句是合法的。
p=a;p++;p+=3;而“a++;”“a=p;”都是错误的。
在使用中应注意*(p++)与*(++p)的区别。若p的初值为a,则*(p++)的值等价于a[0],*(++p)等价于a[1],而(*p)++表示p所指向的元素值加1。如果p当前指向a数组中的第i个元素,则有“*(p--);”等价于“a[i--];”,“*(++p);”等价于“a[++i];”,“*(--p);”等价于“a[--i];”。
【例7.8】分析程序的运行结果。
运行结果:
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。