指针的算术运算

指针有以下两种算术运算:
(1) 指针+/-数字
(2)指针-指针

首先我们来讨论一下 指针+1加的是什么呢?有以下三种猜想:
1> 加一个字节
2> 加一个单元格

3> 加整个数组

1> 若加的是整个数组的话,直接从数组的首部跑到尾部了,起不到遍历数组中每个元素的作用,所以这种想法是错误的;
2> 若加的是一个单元格,如下所示
int a[10]={1,2,3,4,5,6,7,8,9,10};
int *p=a;
假设数组a的首地址为100,这时数组a中的元素存放位置如下所示:
     100        104          108         112         116         120         124        128          132         136
123456789

10

*p=10;
现在我们只看上表的前两个单元格,一个字节8位,int型为4个字节,每个单元格32位,我们将其扩大4倍,得到的每个新单元格存放8位,8位太长,所以我们用16进制表示,a[0]=10,a[1]=2,其对应的16进制分别为0000000a,00000002,按小端存放,地地址放小数据,如下所示:
     100         101         102         103        104         105         106          107
0a00000002000000
p++;
*p=20;
20对应的十六进制为00000014,如果p++加的是一个单元格,如下所示:
     100         101         102         103         104         105         106        107
0a14000000000000

a[0]=0x0000140a,a[1]=00000000,对应的十进制分别为a[0]=5130,a[1]=0,这种方法很麻烦,得到的结果也不是我们想要的,所以不采用这种想法;当然这种方法可用如下程序实现:

#include <stdio.h>
int main() 
{
int a[10]={1,2,3,4,5,6,7,8,9,10};
int *p=a;
*p=10;
p=(int *)((int)p+1);
*p=20;
printf("%08x  %08x\n",a[0],a[1]);
printf("%d  %d\n",a[0],a[1]);
return 0;
}

结果如下:

综上所述:指针+1:加一个单元格
                指针-1:减一个单元格
(1)指针+/-数字:需要调整,调整的权重为sizeof(指针去掉一个*)

int main()
{
	int *p=(int *)2000;
	printf("%d\n",p+4);//2016 
	//指针p加4个单元格,每个单元格4个字节,2000+4*4=2016
	printf("%d\n",(short *)p+4);//2008
    //short *去掉一个*为short,short 2个字节,指针p加4个单元格,每个单元格2个字节,2000+4*2=2008
	printf("%d\n",(double *)p+4);// 2000+4*8=2032
	printf("%d\n",(double **)p+4);// 去掉一个*为(double *),指针4个字节,2000+4*4=2016
	printf("%d\n",(float *)p+4);//2000+4*4=2016
	printf("%d\n",(unsigned short *)p+4);// 2000+4*2=2008
	printf("%d\n",(long *)p+4);// 2000+4*4=2016
	printf("%d\n",(char *)p+4);// 2000+4*1=2004
	printf("%d\n",(unsigned long long)p+4);//括号内没有* ,p为普通变量,2000+4=2004
	return 0;
}
int main()
{
	int *p=(int *)0x2010;
	printf("%x\n",p-2);//2008
	//指针p减2个单元格,每个单元格4个字节,0x2010-2*4=2008
	printf("%x\n",(short *)p-2);//200c
	//short *去掉一个*为short,short 2个字节,指针p减2个单元格,每个单元格2个字节,0x2010-2*2=200c
	printf("%x\n",(unsigned long *)p-2);//0x2010-2*4=2008
	printf("%x\n",(long long *)p-2);//0x2010-2*8=2000
	printf("%x\n",(float *)p-2);//0x2010-2*4=2008
	printf("%x\n",(double *)p-2);//0x2010-2*8=2000
	printf("%x\n",(char *)p-2);//0x2010-2*1=200e
	printf("%x\n",(unsigned long)p-2);//括号内没有* ,p为普通变量,0x2010-4=200e
	return 0;
}

(2)指针-指针:间隔的单元个数,不是字节数,有正负
1> 算出字节数     2> 除以调整的权重

int main()
{
	int arr[10]={1};
	int *p=&arr[1];
	int *q=&arr[9];
	printf("%d\n",p-q);//-8  
	printf("%d\n",q-p);//8
	printf("%d\n",(short *)q-(short *)p);//16 
	//q-p间隔8个单元格,每个单元格4个字节,共32个字节,short *去掉一个*为short,short 2个字节,32/2=16
	printf("%d\n",(double *)q-(double *)p);// 32/8=4
	printf("%d\n",(int ***)q-(int ***)p);// int ***去掉一个*为int **,int ** 4个字节,32/4=8
	printf("%d\n",(char **)q-(char **)p);// char **去掉一个*为char *,char * 4个字节,32/4=8
	printf("%d\n",(long)q-(long)p);//32 
}

总结:指针的所有算术运算都需要调整,调整的权重为sizeof(指针去掉一个*)











  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值