指针算术加减运算
在指针学习中,我们知道指针存放的也是具体的值。我们可能就会思考,指针能否进行常规的运算呢?
其实,指针的也是可以进行运算的,那么指针是怎么进行运算的呢?我们来分析一下。
例如在一个数组arr[]中,我们定义一个指针*p,这个指针指向数组的第一位,此时我们对这个指针进行+1运算。此时这个指针加的到底是什么呢?+1个字节?+1个单元格?+1个数组?
从正常的思维来想的话,应该加的是一个单元格。如果我们加的只是一个字节,此时我们的指针后移一个字节,此时的影响就会如下图所示:
此时arr这个数组中的数字基本都会受到影响,我们得到的就会是错误的信息。
如果这个指针+1是加一个数组的话,我们当前的数组就跳过了,这不是我们想要的结果。所以说在数组中,指针+1指的就是加一个单元格,也就是一个数据的整个地址,减去的就是其一个数据的数据类型所占的字节数。减法即是同理。
#include <stdio.h>
//指针的算术运算 +,-
//1.指针+i,表示加i个单元格,其加i*sizeof(指针本身去掉一个*)字节
//2.指针+i,表示加i个单元格,其加i*sizeof(指针本身去掉一个*)字节
int main()
{
int *p = (int *)2000;
printf("%d\n",p-2);//2000-2*sizeof(int)=1992 int类l数据占4个字节
printf("%d\n",(char *)p-2);//2000-2*sizeof(char)=1998 char类型数据占1个字节
printf("%d\n",(short *)p-2);//2000-2*sizeof(short)=1996 short类型数据占2个字节
printf("%d\n",(long long *)p-2);//1984 long类型数据占8个字节
printf("%d\n",(float *)p-2);//1992 float类型数据占4个字节
printf("%d\n",(double *)p-2);//1984 double类型数据占8个字节
printf("%d\n",(int **)p-2);//2000-2*sizeof(int*)=1992 此时去掉一个*是个int *指针类型,
指针在32位系统为4个字节,在64位系统占8个字节。
printf("%d\n",(unsigned long)p-2);//1998**** 此时没有*,只单纯的进行数字运算即可。
return 0;
}
我们还可以讨论一下指针之间的运算。
指针+指针:例如在一个数组arr[]中我们定义两个指针,*p1=arr[2]; *p2=arr[3]; 此时如果我们对他们进行加法运算便是错误的算法。2号数据的地址+3号数据的地址,就好比2号房子的门牌号+3号房子的门牌号,这是个没有意意义的结果。所以指针之间的加法是非法运算。
那么指针-指针是不是也是没有意义的呢?我们和加法一样分析一下,2号数据的地址-3号数据的地址。2号房子的门牌号-3号房子的门牌号,我们从这个结果可以分析出2号房子和3号房子之间隔了一个房子,在数组中就是隔了一个单元格,又因为2号的地址小于3号的地址,得出的数还是个负数。
我们可以在此总结一下:
1.指针+i,表示加i个单元格,其加isizeof(指针本身去掉一个)字节
2.指针+i,表示加i个单元格,其加isizeof(指针本身去掉一个)字节
3.指针+指针,非法运算。
4.指针-指针,表示所间隔的单元格数,可正可负。(先算出间隔的字节数,然后除以sizeof(指针本身去掉一个*))。