之前在学习指针时,我们知道指针其实也是一种变量,既然这样,那么指针应该和普通变量一样,可以进行算术运算。下面我们介绍指针的加减运算。
先看一个实例:
#include <stdio.h>
int main()
{
int arr[10] = {1,2,3,4};
int *p = arr;
*p = 10;
printf("%d\n",*p);
p++;
*p = 20;
printf("%d\n",*p);
return 0;
}
关于上述实例中的p++,可能会有以下三种情况:
1.加一个数组;
2.加一个字节;
3.加一个指针。
在上述例子中,我们定义了一个整形数组arr,p指向数组首地址。假设其首地址为1000,则整个数组对应的地址如下:
图1 数组arr对应地址
*p = 10,是将数组首元素的值改为10:
图2 修改数组arr首元素的内容
第一种情况:加一个数组;
图3 指针p向后移一个数组
这种情况是无意义的。使用指针的目的就是访问数组内的元素,若为加一个数组,则直接到数组的后一个地址,并没有访问数组内元素,所以这种情况可以排除。
第二种情况:加一个字节;
数组arr为整型,每一个单元格占4个字节,我们把前两个单元格用字节的形式画出。arr[0]=10,十进制的10转化为十六进制为0xa。a占用4个字节,也就是8位,即0x0000000a。十进制的2转化为十六进制为0x00000002。因电脑使用的小端,即低地址存放小数据,如下图所示:
图4 前两个数组元素
当p为加一个字节时,将*p赋值为20,十六进制为0x00000014,则:
图5 指针p加一个字节
此时arr[0]的值为0x140a,转化为十进制为5130。arr[1]=2,显然与我们想要的结果不符。
第三种情况:加一个单元格;p向后加一个单元格,即指向arr[1]。将arr[1]修改为20,如图:
图6 指针p加一个单元格
将arr[0]和arr[1]转化为十进制分别为10,20,此时结果才是正确的。说明对于整型指针p++,应为加一个单元格,也就是四个字节。因此指针的加法和减法是需要调整的,调整的权重是sizeof(指针去掉一个*)。
下面是指针加法的一些实例:
#include <stdio.h>
int main()
{
int *p = (int *)1000;
printf("%d\n",p+5);//1020
printf("%d\n",(short *) p+5);//1010
printf("%d\n",(unsigned long *)p+5);//1020
printf("%d\n",(double *)p+5);//1040
printf("%d\n",(char ***)p+5);//1020
printf("%d\n",(char *)p+5);//1005
printf("%d\n",(long long)p+5);//1005
return 0;
}
运行结果:
图7 指针加法实例运行结果
下面是指针减法的一些实例:
#include <stdio.h>
int main()
{
int *p = (int *)0x2010;
printf("%x\n",p-2);//2008
printf("%x\n",(float *) p-2);//2008
printf("%x\n",(double **)p-2);//2008
printf("%x\n",(long long *)p-2);//2000
printf("%x\n",(short *)p-2);//200c
printf("%x\n",(char *)p-2);//200e
printf("%x\n",(unsigned long)p-2);//200e
return 0;
}
运行结果:
图8 指针减法实例运行结果
指针加指针非法,指针减指针表示两个指针间隔的单元格数。计算方法:1.算出字节数;2.除以调整权重。下面是指针减指针的实例:
#include <stdio.h>
int main()
{
int arr[10] = {0};//x
int *p = &arr[9];//x+36
int *q = &arr[1];//x+4
printf("%d\n",p-q);//8
printf("%d\n",q-p);//-8
printf("%d\n",(short *)p-(short *)q);//16
printf("%d\n",(long *)p-(long *)q);//8
printf("%d\n",(char **)p-(char **)q);//8
printf("%d\n",(double *)p-(double *)q);//4
printf("%d\n",(long long)p-(long long)q);//32
printf("%d\n",(char *)p-(char *)q); //32
return 0;
}
运行结果:
图9 指针减指针实例运行结果