指针数组的加一操作及指针运算

今天和大家探讨一下下面代码中的指针进行P++操作的几种可能性及哪种方式更合理

int main()  
{  
    int arr[] = {1,2,3,4,5,6,7,8,9,10};  
    int *p = arr;  //定义一个整型指针变量p保存整形数组arr的首地址
    *p = 10;  //通过解引用访问arr[0]
    p++;  
    *p = 20;  //p进行加一操作后重新赋值  
    printf("十进制 %d,%d\n",arr[0],arr[1]);  
    printf("十六进制 %08x,%08x\n",arr[0],arr[1]);  
    return 0;  
}  

根据此处的情况加一操作有如下几种可能性:

1.加一个字节

2.加整个数组的长度(数组长=sizeof(arr)/sizeof(arr[0]))          直接否定,没有操作意义

3.加一个数组单元格(此处指的是4字节)

情况1:加一个字节

我们令arr[0]=2  ,arr[1]=10存储地址分别为100,104,一个元素占四个字节


接下来考虑如何存放数据的问题,我们引入中间进制,将100这个地址的单元格细化为八个单元格,相比之下采用十六进制存放数据更适合八个单元格的布局,下面就要分析存储顺序的问题:存储单元从左到右依次是低地址到高地址,低地址放大数据称为大端,低地址放小数据称为小端,我们的操作以小端为准。2和10写成16进制数分别为00 00 00 02和00 00 00 0a,将这两个数存放如下图:



扫描二维码关注公众号,回复: 4988246 查看本文章

没有进行加一操作前结构是合理的。

下面实现猜想的内容,将20保存后移动一个字节得到下图:

20的16进制为00 00 00 14


此时就存在问题了,再用下面用代码一探究竟

#include <stdio.h>
int main()  
{  
   int arr[] = {1,2,3,4,5,6,7,8,9,10};  
    int *p = arr;  
    *p = 10;  
    p = (int *)((int)p+1); //让 p 只加一个字节  
    *p = 20;  
    printf("%08x,%08x\n",arr[0],arr[1]); //分别输出arr[0] 、arr[1] 的八位十六进制  
    return 0;  
} 

既然后移一个字节,输出结果为0000140a,00000000,前者用十六进制换算下来是5130

明显得到的数字换算之后和自己给的数据差距很大,如果真的p++是进行加一字节的操作可能会造成不可预料的后果。因此p++操作加一个数组单元格是最合理的,它可以准确的指向某一个确定的位置,迅速的完成解引用。通过这一番讨论不难看出指针和数字间的操作并不是一步到位,它有一个中间过程,期间的数据转换取决于指针的数据类型,数据类型不同自然单元格长度不同,这就是p++操作是移动单元格而不是其他操作的原因。
接下来谈谈指针的几种运算:
1.指针+数字
#include <stdio.h>
int main()
{
int*p=(int*)2000;//用int*进行强转,保证等号两边数据类型一致
p+4;
printf("%d",p+4);
printf("%d",p-4);
return 0;
}

结果:2016  1984


指针的加法需要进行一个微调整,调整权重(sizeof(数据类型)), 此处的数据类型为指针去到一个*,二级指针也不例外。比如将上述代码中的红色部分被改为 printf("%d",(double**)p+2); 输出值为2000+8=2008
指针的减法我们也采用调整权重的方法,要注意的就是对于二级指针到一级指针的转换问题。说到这可能有人问指针可不可以和指针相加,显然是没有意义的,首先说你想得到啥,关键是本质上就得不到任何实际上的结果。但是指针间的减法就不同,8它至少可以得到一个区间,然后我们去研究它的用处。在指针数组中我们单纯在字节层面上讨论似乎没多大意义,因为我们 常说一个单元格存什么而不是说几个字节存什么。自然指针的 减法运算直观的得到的是两个指针间单元格的数目。
#include <stdio.h>
int main()
{
	int arr[10] = { 0 };
	int *p = &arr[1];
	int *q = &arr[9];
	printf("%d\n", p - q);
	printf("%d\n", q- p);
	printf("%d\n", (float*)q - (float*)p);//调整力度为字节数之差/权重
	printf("%d\n", (double*)q - (double*)p);
	printf("%d\n", (short*)q - (short*)p);
	printf("%d\n", (long**)q - (long**)p);
	return 0;
}

结果:-8 8 8 4 16 8















猜你喜欢

转载自blog.csdn.net/zhanxiao5287/article/details/79852529