指针加减法

指针加减法有以下几种情况;咱分开讨论:

指针加法

做加法之前呢,我们先做这样一件事:我们首先定义一个数组,保存1,2,3这三个数,假设一个单元格代表四个字节,地址从100 开始,

编写一个程序:

那么这就有问题了,那么“*p = (int *)((int) arr + 1);”是加的1什么,一个字节?一个单元格?还是整个数组?

首先排除掉加的整个数组,若是加的整个数组长度的话,将会直接跳到数组最后;无意义,那么要是加一个字节呢?我们来分析分析:

为了方便理解,我们将这个数组放大四倍(一个格子代表一个字节)

然后放入数据,先将数据转化为十六进制(因为一个字节有八位二进制数,一个十六进制数恰好是四位,一个字节刚好存放两个十六进制数),根据低地址存放小数据这个规则进行填充,填充后如图所示:

然后进行加一个字节,那么我们这个数据应该变为00 00 00 02 00 00 00,但是我们放数据是根据低地址存放小数据,所以我们在读取数据时候应该反着来,即:0x02 00 00 00;2前边的0可以省略,结果即:2000000,进行验证

我们会发现,这个程序编译的数字已经很大了,要是程序中的数字在大点就会更大,所以,这个不是我们想要的

那么就只有加一个单元格了,也就是加相应类型的字节数,

char :1个字节
short : 2个字节
int:  4个字节
float:  4个字节
double:   8个字节
long:   4个字节

long long:  8个字节

unsigned long:  4个字节

通过以上分析呢,得出以下规则

1.指针+数字,

对于指针+数字这一点来说呢,我们定义所加的数字数为单元格数,指针加法需要调整,调整的权重为sizeof(指针去掉一个*)

// 
 

eg:

 int *p = (int *)1000;
 printf("%d\n",p+1);//1004
 printf("%d\n",p+4);//1016
 printf("%d\n",(char *)p+4);//1004
 printf("%d\n",(short *)p+4);//1008
 printf("%d\n",(double *)p+4);//1032
 printf("%d\n",(unsigned long long )p+1);//1001
 printf("%d\n",(int ***)p+1);//1004记住是去掉一个*号后求sizeof
 printf("%d\n",(double **)p+1);//1004
 printf("%d\n",(float **)p+10);//1040
 return 0;
}

2.指针-数字

同理呢,指针减法也是一样的:指针减法需要调整,调整的权重为sizeof(指针去掉一个*)

eg:

int main()

{
int *p = (int *)0x2020;
printf("%x\n", p - 2);//2018
printf("%x\n", (short *)p - 2);//201c
printf("%x\n", (double *)p - 2);//2010
printf("%x\n", (long long ***)p - 2);//2018
printf("%x\n", (float *)p - 2);//2018
printf("%x\n", (char *)p - 2);//201e
printf("%x\n", (unsigned long long)p - 2);//201e
return 0;

}

既然有指针加数字呢,我们是不是应该会想到指针+指针呢?当然了,有这个想法是好的,这个指针+指针是非法的;所以不予考虑;所以就剩下指针-指针这种情况了

3.指针-指针有分两步进行

(1)算出间隔字节数

(2)除以调整的权重

eg:

int main()
{
int arr[20] = { 0 };
int *p = &arr[2];//x+8
int *q = &arr[8];//x+32
printf("%d\n", p - q);//-6
printf("%d\n", q - p);//6
printf("%d\n", (short *)q - (short *)p);//12
printf("%d\n", (long *)q - (long *)p);//6
printf("%d\n", (float *)q - (float *)p);//6
printf("%d\n", (long long **)q - (long  long **)p);//6
printf("%d\n", (double *)q - (double *)p);//3
printf("%d\n", (char *)q - (char *)p);//24
printf("%d\n", (long)q - (long)p);//24
return 0;

}

那么我们就愉快的学会了新的知识。开心不

  • 33
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值