上一篇主要討論了C指針的本質(zhì),但并沒有解釋指針的類型問題,這次我們重點來討論指針的類型與指針內(nèi)存分配之間的關(guān)系。
對比以下兩個指針
int *p;
char *p;
單純從上面看這兩個指針有何區(qū)別?
很多讀者第一反應(yīng)就是其類型不同,確實沒錯,但是我們現(xiàn)在需要從底層出發(fā),搞清楚指針類型的意義。
其實單純從上面來看,兩個指針是沒有任何區(qū)別的,其內(nèi)存的大小完全相同。
但是由于指針有++和--操作,導(dǎo)致指針的偏移量大小到底多大,這個就需要由類型決定。 因此類型僅僅只決定指針移動時偏移的大小。
下面我們來徹底分析指針這個問題。
從程序員開始寫int *p這句時,計算機僅僅為p分配了一個四字節(jié)的內(nèi)存地址(假設(shè)編譯器為32位),而這個內(nèi)存地址中存儲的數(shù)據(jù)是多少并不知道,由于其數(shù)據(jù)可能是一個隨機數(shù),因此我們強行訪問p時會得到一些隨機的數(shù)字,這又一步說明了指針為啥需要進行初始化,但是,我們?nèi)绻榭?p時,我們可以看到這是合法的,因為我們查看的是p的地址, 即計算機為p分配的一個內(nèi)存地址,如圖所示:
這個可能比較好理解
我們現(xiàn)在開始深入,看如下:(下面代碼摘自作者寫的嵌入式操作系統(tǒng))
typedef struct PCB_STRUCT
{
struct PCB_STRUCT *TCBPrev; //前趨指針
struct PCB_STRUCT *TCBNext; //后繼指針
UINT32 TCBDlyCount; //延時計數(shù)器
UINT8 TCBState; //任務(wù)狀態(tài) 255為頭部 254尾部 0表示阻塞態(tài),1表示就緒態(tài),2表示掛起態(tài)
INT8 *TCBName; //任務(wù)名
FUN TCBTask; //任務(wù)函數(shù)指針
UINT8 *TCBStack; //人工堆棧
UINT8 TCBPrio; //任務(wù)優(yōu)先級
pTCB *TCBHandler; //任務(wù)句柄 也叫任務(wù)ID
UINT16 TCB_SP; //任務(wù)當前的SP指針
}pTCB;
現(xiàn)在我們定義
pTCB *RdyTab[33]; //就緒查找表 0為空閑任務(wù)
我們現(xiàn)在思考:
RdyTab[33]的內(nèi)存分配結(jié)構(gòu)?
部分讀者會有第一反應(yīng)就是內(nèi)存結(jié)構(gòu)當然是33個結(jié)構(gòu)體的大小。 如下:
其實上面是錯誤的
因為之前說過,即使是結(jié)構(gòu)體指針數(shù)組,其數(shù)組的元素本質(zhì)上仍是指針,因此,其大小也只是一個四字節(jié)的地址單元,因此,其正確的結(jié)構(gòu)如下:
那有人會有疑惑,為啥
RdyTab[i]->TCBPrev等等,這些為什么存在呢?
其實這個并不存在,這里單純指RdyTab[i]的內(nèi)存單元中,而我們需要使用RdyTab[i]->TCBPrev等等
時,必須先初始化RdyTab[i]的值,而這個RdyTab[i]->TCBPrev就是指初始化時指向內(nèi)存的首地址
偏移位置,這個工作是由編譯器完成的,如下圖所示!
顯然當我們使用RdyTab[i]->TCBPrev時,其地址就是分配的結(jié)構(gòu)體所在的地址,而不是指針數(shù)組的地址。
-
內(nèi)存
+關(guān)注
關(guān)注
8文章
3028瀏覽量
74082 -
指針
+關(guān)注
關(guān)注
1文章
480瀏覽量
70569 -
數(shù)組
+關(guān)注
關(guān)注
1文章
417瀏覽量
25960 -
C指針
+關(guān)注
關(guān)注
0文章
10瀏覽量
6401
發(fā)布評論請先 登錄
相關(guān)推薦
評論