數組的首地址,數組名取地址,地址的強制轉換爲int

#include <stdio.h> 

int main()
{
int a[5]={7,8,9,10,11};
int *ptr1=(int *)(&a+1);
int *ptr2=(int *)((int)a+1);

printf("%d\n",&a);
printf("%d\n",(int)a);
printf("%d,%d\n",ptr1,ptr2);
printf("%d,%x\n",ptr1[-1],*ptr2);


return 0;
}

輸出結果:

1245036
1245036
1245056,1245037
11,8000000
Press any key to continue
結果怎麼會是這樣的呢???特別是&a,(int)a的值都是1245036 那麼分別加以後怎麼結果不是一樣的???還有就是*ptr2的值(十六進制)是:80000這個值不是隨機數呢??(我開始認爲是的,但實際不是的),讓我們來一起分析一下:

首先我們要知道a[5]={7,8,9,10,11};的意思:在內存中開闢一個數組大小是: sizeof(int)*5=4*5=20個字節(一個整形佔4個字節),那麼數組名a的值就是這片內存單元的首地址

我們看到printf("%d\n",&a);printf("%d\n",(int)a);輸出的結果:1245036 1245036,我們可以知道&a是上面內存單元的首地址,(int)a是把首地址轉換成int的數據。

int *ptr1=(int *)(&a+1); 其中&a+1,不是簡簡單單的加一,而是加上數組的大小(表示指針移到數組內存單元的最後的下一個單元地址)爲什麼???那是因爲系統在內存中(具體的說應該是棧中)爲數組分配一個連續大小爲20字節的大小,並把首地址賦值給數組名a,那麼&a+1就是表示這個內存的下一個地址,這個加一不是我們平時說的整數1,而是數組的大小即1245036+20=1245056,那麼指針變量ptr1就是指向此內存單元,那麼*ptr表示地址爲1245056單元的內容,而ptr1[-1]等價於*(ptr1-1),ptr1-1即先把指針後移一個,不是指向數組的最後一個元素嗎??,那麼*(ptr1-1)不就是數組最後的值嗎???即11,十六進制是b

而int *ptr2=(int *)((int)a+1); 就是在1245036+1=1245037,這又是爲什麼???原因很簡單那是因爲:(int)a表示的把數組地址即內存單元的編號轉換成整數,那麼此時的(int)a+1加一相當於加一個整數!!

注意1245037在於數組第一個和第二個元素地址中間(可以數組數組的第一元素和第二個元素的地址分別是:1245036 1245040),那麼*ptr2的值就是第一個元素的二進制和第二個元素的二進制的組合:那我們看看數組第一元素和第二個元素的二進制是:

7的二進制:0000 0000 0000 0000 0000 0000 0000 0111

8的二進制:0000 0000 0000 0000 0000 0000 0000 1000

那麼*ptr2的值就是從7的二進制的第二個字節開始數四個字節(即取7的後三個字節和8的第一個字節):

0000 0000 0000 0000 0000 0111 0000 0000

注意在內存是先放低字節,然後是高字節,那麼計算的時候的到過來即:0000 0000 0111 0000 0000 0000 0000 0000 0000

那麼對應的十六進制是:0080000,即80000

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章