zoukankan      html  css  js  c++  java
  • 指针偏移量的理解

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

     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;
    }
    

    输出为:

  • 相关阅读:
    模糊查询的like '%$name$%'的sql注入避免
    在VS2010中使用Git(转)
    android WebView解析 调用html5
    git
    推荐!手把手教你使用Git
    羽毛拍十大品牌
    乒乓球拍板和皮子世界排名
    足球小记
    centos 网络启动 在/etc/sysconfig/network-scripts/ifcfg-eth1onboot=yes即可
    MyEclipseGen--------生成
  • 原文地址:https://www.cnblogs.com/hellovan/p/11406986.html
Copyright © 2011-2022 走看看