指针偏移量的理解

摘要:
intmain(){intarray〔2019〕={0};阵列[19]=2019;unsignedlongoffset=(unsignedlong)((短*)数组+2019)-(unsigned long)(数组+*(unsignendchar*)(数组+19));抵消对于((短*)阵列+2019)。

今天刷题的时候碰到如下的一道题:

 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("内存中存储情况:
");
	for (int n = 0; n < 4; n++)
		printf("  0x%x	%02x
", &i + n, c[n]);
	printf("实际的16进制形式:
");
	printf("  0x%08x
", i);
	return 0;
}

输出为:
指针偏移量的理解第1张

免责声明:文章转载自《指针偏移量的理解》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇(转载)CPU、内存、硬盘、指令以及他们之间的关系借助强大的IDEA开发ide高效实现equals,hashcode以及toString方法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

iOS 编译过程原理(2)

一、前言 《iOS编译过程的原理和应用》文章介绍了 iOS 编译相关基础知识和简单应用,但也很有多问题都没有解释清楚: Clang 和 LLVM 究竟是什么 源文件到机器码的细节 Linker 做了哪些工作 编译顺序如何确定 头文件是什么?XCode 是如何找到头文件的? Clang Module 签名是什么?为什么要签名 为了搞清楚这些问题,我们来挖...

Perl脚本学习经验(二)常用命令举例

一.chomp   作      用:去除读入字符串的换行符,去除\n或者\r\n:   简单举例:    while(<FDATA>)    {        my $tmp_record = $_;        chomp ($tmp_record);    }        简单说明:此时$tmp_record变量的结束处已经不包含换行...

Linux网络编程——进程池实现过程详解(2)

进程池功能升级: send_recv_syn同步机制 自定义设置函数recvCycle,确保双方收发机制正常 客户端中显示下载进度 time/slice两种方法 设置异常情况 客户端在下载中突然断开,原先的服务端会一直死循环打印 服务器突然断开,客户端全部死循环 服务器断开后,再次执行同一端口会出现异常 服务器要升级,通知客户端有序退出 如果业务...

中移4G模块-ML302-OpenCpu开发-(MQTT连接阿里云-RRPC通讯)

B站:https://space.bilibili.com/309103931 中移4G模块-ML302专栏:https://blog.csdn.net/qq_33259323/category_10453372.html 中移4G模块-ML302文集:https://www.bilibili.com/read/readlist/rl328642 1.中移...

二维数组指针

     最近复习C语言的时候用到了2维数组的指针做为函数形参传入,网上查了一些方法,觉得颇有深度,做了一番研究,感受颇深,写下来算是做为第一天来博客园的见证。     首先网上查了一下,就是传入2维数组指针来作为对参数的形参,如 int (*a)[2],int a[2][2] 等形式; void fun(int a[][2]) { a[1][1]=3;...

Linux下Socket的简单使用及最简化封装

Linux下Socket的简单使用及最简化封装 /** 文件功能: linux 下套接字简化操作函数* 文件名称: linux_socket.h* 建立时间: 2007 年 07 月 19 号* 创建作者: wlzqi* 使用语言: C 或 C++ 语言* 使用环境: Linux + Windows* 函数要求: *    + 函数相对比较底层*    +...