07.09 結構體指針強制轉化

hello小夥伴們中午好!今天我們來聊聊結構體指針強制轉化!

結構體指針強制轉化

類型轉換也可以根據如下理解:

例如:b->num : 將 struct A a 所指向的內存單元以 struct B b的分佈方式(利用 b)取得偏移為num 的值。

結構體成員聲明該成員在結構體中的偏移地址。

解釋如下:

1、首先要明確struct B b本身有一個值(在32位機上一般是32位),這個值代表著某個內存地址,比如這個首地址值是0x30000000,由於b被定義Struct B類型,那麼編譯器在編譯源文件時就會認為b指向的是一個struct B的結構,這個結構的內容由一段連續的內存存儲,(b->num)(b->type)(b->age)在struct B的定義中肯定是存在num、type、age三個的,這幾個變量對一個struct B結構的地址偏移量是固定的,也就是說只要知道一個struct B結構的起始地址,就能計算出這個結構所包含的num、type、age的地址,由於B b的地址已知(由A a強制轉換而來,所以編譯器知道這個地址即a的首地址),b所含的num離b的偏移量已知,那麼就能通過b實現對num的取值,在編譯器編譯C文件的時候並不管b中的nun是否定義

2、b被定義為struct B,而B中又包含b,那麼編譯器就認為b所指向的結構中存在num

3、b->num如果不發生保護錯誤,總是能取到一個值(這個值就是對b偏移一定距離的內存單元中的值),只是這個值不能確定是否是你期望的值

4、再次提醒,變量的值是存儲在內存中的,每個內存字節對應一個內存地址,而內存存儲的值本身是沒有整型,指針,字符等的區別的,區別的存在是因為我們對它們有不同的解讀,b的值就是一個32位值,並且存儲在某個內存單元中,通過這個32位值就能找到b所指向的結構的起始地址,通過這個起始地址和各個結構所包含變量離起始地址的偏移對這些變量進行引用,b->num只是這種引用更易讀的寫法,只要b是指向num 的指針,那麼b的值就肯定存在,b存在,偏移量已知,那麼b->num就肯定存在,只是要記住,b->num只是代表了對num一定偏移地址的值

5、假如b->num所對應的這段內存從未有進行過操作,那麼其值就是系統上電啟動之後的內存的默認值,如果有其他程序使用過,那麼其值就是其他程序執行後在這段內存中留下的值,總之,每個正常工作的內存單元中都是有值的,無論這些值是否是我們所需要的,它們始終是存在的。你可以把內存想象成一個大數組,當你在程序中定義了一個數組,但是並沒有初始化,但是你也可以引用數組元素,只是引用的值是未知的,道理是類似的

2、將int強制類型轉換為結構體類型

typedef struct eg

{

int x;

int y;

}eg;

int point = 0x30000000;

eg peg = (eg)point;

可以看到point本身只是個整型變量,但是這樣的賦值是合法的,peg->x的值是0x30000000開始的四字節,peg->y是0x30000004開始的四字節。

解釋如下:

不是說某個地址有那個結構體你才能引用,即使沒有,你也能引用,因為你已經告訴了編譯器param變量就是指向一個PAINT_PARAM結構體的變量並且指明瞭param的值,機器碼的眼中是沒有數據結構一說的,它只是機械的按照指令的要求從內存地址取值,那剛才的例子來說,peg->x,peg->y的引用無論0x30000000是否存在一個eg結構體都是合法的,如果0x30000000開始的8個字節存在eg結構體,那麼引用的就是這個結構體的值,如果這個位置是未定義的值,那麼引用的結果就是這8個字節中的未定義值,內存位置總是存在的,而對內存中值的引用就是從這些內存位置對應的內存單元取值。

好啦,今天的有關內容奉送完畢!更多精彩內容詳細關注百戰程序員哦!另外,大家喜歡這篇文章可不可以點擊文章上方的關注呀!小編會為大家提供更多實用的文章哦!

結構體指針強制轉化


分享到:


相關文章: