指针的“加、减” 运算,指针存储(c语言)

首先我们来复习指针的基本知识:

int a=10;        //定义一个整型变量a,并将10赋值给a;

int *p=&a;      //定义一个整型指针变量p,并将a的地址赋值给p;

p=(int *)1000;  //将(int)1000强转为整型指针(int *),并赋值给p;

               

指针变量的大小(4个字节):

     在c语言中,内存可以理解为一个字符数组,基本单位是字节,每个字节包含一个地址,而地址是由CPU的地址总线位数决定的,所有的地址一般称为地址空间,比如32位的CPU,地址总线的位数是32位,它可以描述地址空间为0x0000 0000 0000 0000~(2^32-1),又因为1(字节)=8(位),所以32位的系统(还和编译器有关,编译器是32位),指针变量占4个字节。(64位编译器,指针变量占8个字节)

 理解指针“加、减”运算:

int arr[8]={1,2,3,4,5,6,7,8};   //定义一个整型一维数组arr,并赋值;

int *p1=arr;   //定义整型指针变量p1,指向arr[0](存储arr[0]的地址)

p1++; 


此时p1是加一个字节?一个格子(4个格子)?

   假设:p1++是加一个字节;

            :p1=3;  //p1++执行后执行

   此时,arr[0]==?


显然,如果这样移动,指针将变得极其复杂,还会引起数据混乱,所以假设不成立!

    若p1++是一个格子:

:p1=3;  //p1++执行后执行

   此时,arr[1]==3;


结果成立!

同理得:
        int arr[10] = {1};
int *ip = arr;
ip++;//加一个整型单元格,4字节

short brr[10] = {20,10,30,0x7234};
short *sp = brr;
sp++;//加一个short单元格,2字节

double crr[3] = {12.3};
double *dp = crr;//brr

dp++;//加一个单元格,8字节

指针“加、减”数字(结果还是指针):

int main()
{
	
	int *p = (int *)2000;//(强行转换类型)变量或常量,2000是(int *)类型

	printf("%d\n",p+2);//2008,int 4个字节
	printf("%d\n",p-2);//1992

	printf("%d\n",(short *)p+2);//2004, short 2个字节
	printf("%d\n",(short *)p-2);//1996

	printf("%d\n",(float *)p+2);//2008, float 4个字节
	printf("%d\n",(float *)p-2);//1992

	printf("%d\n",(double **)p+2);//2008, double * 4个字节
	printf("%d\n",(double **)p-2);//1992

	printf("%d\n",(char *)p+2);//2002, char 1个字节
	printf("%d\n",(char *)p-2);//1998

	printf("%d\n",(unsigned long)p+2);//2002,p已经是usigned long类型,p+2b不是指针加法
	printf("%d\n",(unsigned long long)p+2);//1998
	return 0;
}

指针“减”指针(指针加指针是非法的)(结果是整型常量)

    (常用于两个指针指向同一个数组)
int main()
{
	int arr[10] = {0};
	int *p = &arr[1];//a[0]的地址若为x,则&arr[1]==x+4
	int *q = &arr[9];//x+36
	printf("%d\n",p-q);//-8
	printf("%d\n",q-p);//8
	printf("%d\n",(short *)q-(short *)p);//16
	printf("%d\n",(long *)q-(long *)p);//8
	printf("%d\n",(float *)q-(float *)p);//8
	printf("%d\n",(long long **)q-(long  long **)p);//8
	printf("%d\n",(double *)q-(double *)p);//4
	printf("%d\n",(char *)q-(char *)p);//32
	printf("%d\n",(long )q-(long)p);//32
	return 0;
}
int main()
{
	int arr[10] = {0};
	int *p = &arr[1];//a[0]的地址若为x,则&arr[1]==x+4
	int *q = &arr[9];//x+36
	printf("%d\n",p-q);//-8
	printf("%d\n",q-p);//8
	printf("%d\n",(short *)q-(short *)p);//16
	printf("%d\n",(long *)q-(long *)p);//8
	printf("%d\n",(float *)q-(float *)p);//8
	printf("%d\n",(long long **)q-(long  long **)p);//8
	printf("%d\n",(double *)q-(double *)p);//4
	printf("%d\n",(char *)q-(char *)p);//32
	printf("%d\n",(long )q-(long)p);//32
	return 0;
}

总结:

1、指针+、- 数字:指针需要调整的权重为 sizeof(指针去掉一个*),结果还是指针;
2、指针 + 指针:
 非法!
3、指针 - 指针 :合法,结果不是指针!表示间隔的单元个数,需要调整的权重为sizeof(指针去掉一个*)
        指针-指针,分两步:(1)算出间隔字节数;(2)除以调整的权重。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值