指針偏移量的理解


今天刷題的時候碰到如下的一道題:

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

輸出為:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM