指针偏移量的理解
Posted hellovan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了指针偏移量的理解相关的知识,希望对你有一定的参考价值。
今天刷题的时候碰到如下的一道题:
int main() int array[2019] = 0 ; array[19] = 2019; unsigned long offset = (unsigned long)((short*)array + 2019) - (unsigned long)(array + *(unsigned char*)(array + 19)); cout << offset;
以上程序的输出是多少?
仔细一看,这里面各种指针操作,让人一眼看去就有放弃的冲动。其实不急,按照一层一层的剥丝抽茧,其实也不是那么难。
首先,对于((short*)array+2019)
中,是把array
指针由int
型指针强制转换为short
型指针,再偏移2019个单位。short
型占2个字节,因而在地址上的偏移量就是2019 * 2 = 4038
;
然后,对于后面的*(unsigned char*)(array + 19)
进行分解:1、array+19
对应得是array[19]
的地址,这个地址存储的数为2019,其写成16进制为0x000007E3
,而(unsigned char*)(array + 19)
就是把这个地址转换为unsigned char
型指针,由于char
型只占1个字节,因而其地址取出来的数只有原来的前1/4内存存储的数据,即E3
,关于为什么是E3
,而不是00
呢?这个放到下面说。所以,*(unsigned char*)(array + 19)
虽然是char型,但其转换为数值为0xE3
,即227。之后再(unsigned long)(array + *(unsigned char*)(array + 19))
就相当于array地址偏移227个单元,偏移量为227 * 4 = 908
。因而输出的offset = 4038 - 908 = 3130
。
关于上面为什么是E3
,而不是00
呢?
这是因为在内存存储中, 是按照字节从低位到高位存储的,测试如下:
int main
int i = 2019;
unsigned char *c;
c = (unsigned char *)&i;
printf("内存中存储情况:\\n");
for (int n = 0; n < 4; n++)
printf(" 0x%x\\t%02x\\n", &i + n, c[n]);
printf("实际的16进制形式:\\n");
printf(" 0x%08x\\n", i);
return 0;
输出为:
以上是关于指针偏移量的理解的主要内容,如果未能解决你的问题,请参考以下文章