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