C语言----指针算术运算

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_41026740/article/details/79595749

指针算术运算分为指针加法运算和指针减法运算。

一、指针加法运算

这里对指针加常数(如int*p,p++)进行讨论

指针加指针   非法

假设指针+1有以下三种情况:

1、加一个单元格 (正确)

2、加一个字节

3、加整个数组(没有意义)

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

(1)首先验证第二种情况,假设指针+1为加一个单元格,根据以上代码分析如下:

注:两个十六进制数可以表示为8个位的二进制数

数据类型int每个单元格为4个字节

十进制的10转化为8位的十六进制数为: 0000000a  //二进制数为32位

十进制的20转化为8位的十六进制数为: 00000014

综上得出:指针+1表示加一个字节是错误的。

结论:指针加法需要调整(加1加一个单元格),调整的权重为指针去掉一个星号*,然后求sizeof,如:

int *p; p++              加4个字节= sizeof(int)

double *p; p++       加8个字节= sizeof(double)

char **p; p++          加4个字节= sizeof(char *)       (指针占4个字节)

int *p;  p+2              加4*2=8个字节= sizeof(int)*2 

int *p;  p+4              加4*4=16个字节= sizeof(int)*4 

根据上面结论给出代码助于理解,代码如下:

#include <stdio.h>
int main()
{
	int *p = (int *)100;
	printf("%d\n",p+4);                   //116
	printf("%d\n",(char *)p+4);           //104
	printf("%d\n",(short *)p+4);          //108
	printf("%d\n",(unsigned long *)p+4);  //116
	printf("%d\n",(long long)p+4);        //104
	printf("%d\n",(char **)p+4);          //116
	printf("%d\n",(int ****)p+4);         //116

	return 0;
}

二、指针减法运算

1、指针减常数运算

#include <stdio.h>
int main()
{
	int *p = (int *)0x2010;
	printf("%x\n",p-2);               //2008
	printf("%x\n",(char***)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",(char*)p-2);        //200e
	printf("%x\n",(unsigned long)p-2);//200e

	return 0;
}
指针加一个数字或减一个数字都需要调整,调整的权重为去星号*取sizeof。

2、指针减指针运算,

指针-指针     表示间隔的单元个数。例子如下:

#include <stdio.h>
int main()
{
	int arr[10] = {0};  //x
	int *p = &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",(char **)q-(char **)p);    //8
	printf("%d\n",(short *)q-(short *)p);    //16
	printf("%d\n",(double *)q-(double *)p);  //4
	printf("%d\n",(char *)q-(char *)p);      //32
	printf("%d\n",(long long)q-(long long)p);//32

	return 0;
}
练习题:

int arr[5];

int *p = arr;//*p = arr[0];

int *q =arr[5];

①p+q有意义吗?(p、q都为指针)

②q-p有意义吗?

答:①没有意义,指针加指针是非法的。

       ②有意义,设数组arr[5]的首地址为100;q表示arr[5]的地址,p表示arr[0]的地址。q-p=120-100=20.

此处的20表示的是间隔的单元个数,而不是字节长度(由数据类型的改变而改变)。


计算间隔的单元个数:

①算出间隔的字节数(正负)

②除以权重(去星号*加sizeof)

以上为我对指针算数运算的总结。



猜你喜欢

转载自blog.csdn.net/qq_41026740/article/details/79595749