要使用指针访问数组中的各元素,需要对指针进行运算。下面先介绍指针运算的规则。
常见的指针运算有:指针加或减一个数、指针自增、指针自减、指针比较等。
假设有以下指针:
- int *p=&i;
设变量i的首地址为20000。
1.自增/自减运算
对指针变量可进行自增/自减运算,例如,执行如下语句:
- p++;
指针变量p的值应该为多少呢?
如果变量p不是指针变量,这时p的值应该是自增1,变为20001。如果p是指针变量,执行p++的结果就不一定了。对于本例,执行以上语句后,p的值为20004。即p每自增一次,指针就指向后一个int型数。
C语言规定,指针每递增一次,将指向后一个基类型元素的内存单元;指针每递减一次,将指向前一个基类型元素的内存单元。也就是相当于执行以下操作:
- pp=p+sizof(*p);
- pp=p-sizeof(*p);
所以,在定义指针变量时,指针变量的类型非常重要。若使用类型不配匹的指针变量,将得到不可预测的结果。
2.指针加减一个整数
指针还可加减一个整数n,例如,执行如下语句:
- p+=3;
与自增/自减类似,这时指针变量p并不是将内存单元地址增加3个字节,而是将p增加3个基类型数的字节宽度,相当于执行以下语句:
- pp=p+3*sizeof(*p);
因此,此时p的值为20000+3*4=20012。
对于指针减去一个整数n的操作与此类似。
需要注意的是,除了对指针加上或减去一个整数外,其他任何算术运算都是非法的。例如,不允许对指针做乘法和除法、不允许两个指针相加、不允许对指针加上或减去一个float型或double型的数据。
3.两指针变量相减
因指针变量保存的是内存地址,将两个内存地址相加没有意义,所以不允许将两个指针相加。但大部分编译器都支持两个指针相减的运算,两指针变量相减所得之差是两个指针所指变量之间相差的元素个数。实际上是两个指针值(地址)相减之差再除以该指针变量类型长度。例如:p1和p2是为两个指向int型变量的指针,运算p1-p2得到的结果如下:
- d=(p1-p2)/4;
即p1的地址值减去p2的地址值,再除以int型数据所占字节数。得到的值为两个变量相隔多少个int型数据位置。
对于两个普通变量的指针,使用这种运算没有任何意义。但是,如果两个指针指向同一个数组,这时计算结果d就表示两个指针之间相差的数组元素个数。例如,有一个数组a,两个指针p1和p2,分别指向数组的不同元素,如图9-18所示。
图9-18 指针相减 |
这时执行p2 p1,其计算过程为:(1009-10000)/4=3。表示a[3]和a[0]之间相关三个数组元素。
不单是指针相减运算,对于指针加上/减去一个整数n、指针自增或自减这些运算,对于普通变量都没多少实际意义,这些运算都主要使用在指针操作数组时。
4.指针比较
指针比较可用来判断两个指针在内存中的位置关系。例如:
- p1>p2
如果以上表达式为true,则表示p1处于高位地址(地址值更大)。
- p1==p2
如果以上表达式为true,则表示两个指针指向同一个地址。
另外,还可用以下关系表达式判断指针是否为空指针:
- p1==NULL
如果表达式值为true,则表示指针p1为空指针。