【时时三省】(C语言基础)通过指针引用数组
山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省
数组元素的指针
一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。指针变量既然可以指向变量,当然也可以指向数组元素(把某一元素的地址放到一个指针变量中)。所谓数组元素的指针就是数组元素的地址。可以用一个指针变量指向一个数组元素。
例如:
int a [ 10 ] = ( 1,3,5,7,9,11,13,15,17,19 );
int * p ;
p = & a [ 0 ];
以上是使指针变量p指向a数组的第0号元素。
引用数组元素可以用下标法(如a [ 3 ]),也可以用指针法,即通过指向数组元素的指针找到所需的元素。使用指针法能使目标程序质量高(占内存少,运行速度快)。
C语言中,数组名(不包括形参数组名)代表数组中首元素(即序号为0的元素)的地址。因此,下面两个语句等价:
p=&a[0];
p=a;
注意:程序中的数组名不代表整个数组,只代表数组首元素的地址。上述“p = a;"的作用是“把a数组的首元素的地址赋给指针变量p”,而不是“把数组a各元素的值赋给p”
在定义指针变量时可以对它初始化,如:
int p &a [ 0 ];
它等效于下面两行:
int *p;
p=&a[0];
当然定义时也可以写成
int * p = a ;
它的作用是将a数组首元素(即a [ 0 ])的地址赋给指针变量p(而不是赋值给*p)。
在引用数组元素时指针的运算
在引用数组元素时常常会遇到指针的算术运算。有人会提出问题:对数值型数据进行算术运算(加、减、乘、除等)的目的和含义是清楚的,而在什么情况下需要用到对指针型数据的算术运算呢?其含义是什么?
前已反复说明指针就是地址。对地址进行赋值运算是没有问题的,但是对地址进行算术运算是什么意思呢?显然对地址进行乘和除的运算是没有意义的,实际上也无此必要。那么,能否进行加和减的运算?答案是:在一定条件下允许对指针进行加和减的运算。
那么,在什么情况下需要而且可以对指针进行加和减的运算呢?回答是:当指针指向数组元素的时候。譬如,指针变量p指向数组元素a [ 0 ],我们希望用p +1表示指向下一个元素a1。如果能实现这样的运算,就会对引用数组元素提供很大的方便。
在指针已指向一个数组元素时,可以对指针进行以下运算:
加一个整数(用+或+ =),如p +1;
减一个整数(用-或- =),如p -1;
自加运算,如p++,++p;
自减运算,如p--,--p。
两个指针相减,如pl -p2(只有pl和p2都指向同一数组中的元素时才有意义)。
分别说明如下:
( 1 )如果指针变量p已指向数组中的一个元素,则p +1指向同一数组中的下一个元素,p-1指向同一数组中的上一个元素。注意:执行p +1时并不是将p的值(地址)简单地加1,而是加上一个数组元素所占用的字节数。例如,数组元素是float型,每个元素占4个字节,则p +1意味着使p的值(是地址)加4个字节,以使它指向下一元素。
p +1所代表的地址实际上是p +1×d,d是一个数组元素所占的字节数(在Visual C++中,对int型,d = 4,对float和long型,d = 4;对char型,d = 1 )。若p的值是2000,则p +1的值不是2001,而是2004。
系统怎么知道要把这个1转换为4,然后与p的值相加呢?不要忘记,在定义指针变量时必须要指定基类型,如:
float * p;
现在p指向float型的数组元素,在执行++p时,系统会根据p的基类型为float型而将其值加4,这样,p就指向float型数组的下一个元素。如果p原来指向a [ 0 ],执行++p后p的值改变了,在p的原值基础上加d,这样p就指向数组的下一个元素a [ 1 ]。
( 2 )如果p的初值为& a [ 0 ],则p + i和a + i就是数组元素a数组a [i]的地址,或者说,它们指向a数组序号为i的元素,这里需要注意的是a代表数组首元素的地址,a +1也是地址,它的计算方法同p +1,即它的实际地址为a +1×d。
( 3 ) * ( p + i )或* ( a + i )是p + i或a + i所指向的数组元素,即a [ i ]。例如,* ( p + 5 )或* ( a + 5 )就是a[ 5 ],即:*(p+5),*(a+5)和a[5]三者等价。实际上,在编译时,对数组元素a[i]就是按* ( a + i )处理的,即按数组首元素的地址加上相对位移量得到要找的元素的地址,然后找出该单元中的内容。若数组a的首元素的地址为1000,设数组为float型,则a [ 3 ]的地址是这样计算的:1000 + 3×4 = 1012,然后从1012地址所指向的float型单元取出元素的值,即a [ 3 ]的值。
说明:[ ]实际上是变址运算符,即将a [ i ]按a + i计算地址,然后找出此地址单元中的值。
( 4 )如果指针变量pl和p2都指向同一数组中的元素,如执行p2 -p1,结果是p2 - p1的值(两个地址之差)除以数组元素的长度。假设,p2指向实型数组元素a [ 5 ],p2的值为2020;pl指向a [ 3 ],其值为2012,则p2 - pl的结果是( 2020-2012 )/ 4 = 2。这个结果是有意义的,表示p2所指的元素与pl所指的元素之间差2个元素。这样,人们就不需要具体地知道pl和p2的值,然后去计算它们的相对位置,而是直接用p2 - p1就可知道它们所指元素的相对距离。
注意:两个地址不能相加,如pl + p2是无实际意义的。