上一篇主要討論了C指針的本質(zhì),但并沒有解釋指針的類型問題,這次我們重點(diǎn)來討論指針的類型與指針內(nèi)存分配之間的關(guān)系。
對比以下兩個指針
int *p;
char *p;
單純從上面看這兩個指針有何區(qū)別?
很多讀者第一反應(yīng)就是其類型不同,確實(shí)沒錯,但是我們現(xiàn)在需要從底層出發(fā),搞清楚指針類型的意義。
其實(shí)單純從上面來看,兩個指針是沒有任何區(qū)別的,其內(nèi)存的大小完全相同。
但是由于指針有++和--操作,導(dǎo)致指針的偏移量大小到底多大,這個就需要由類型決定。 因此類型僅僅只決定指針移動時偏移的大小。
下面我們來徹底分析指針這個問題。
從程序員開始寫int *p這句時,計算機(jī)僅僅為p分配了一個四字節(jié)的內(nèi)存地址(假設(shè)編譯器為32位),而這個內(nèi)存地址中存儲的數(shù)據(jù)是多少并不知道,由于其數(shù)據(jù)可能是一個隨機(jī)數(shù),因此我們強(qiáng)行訪問p時會得到一些隨機(jī)的數(shù)字,這又一步說明了指針為啥需要進(jìn)行初始化,但是,我們?nèi)绻榭?p時,我們可以看到這是合法的,因為我們查看的是p的地址, 即計算機(jī)為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ù)當(dāng)前的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)當(dāng)然是33個結(jié)構(gòu)體的大小。 如下:

其實(shí)上面是錯誤的
因為之前說過,即使是結(jié)構(gòu)體指針數(shù)組,其數(shù)組的元素本質(zhì)上仍是指針,因此,其大小也只是一個四字節(jié)的地址單元,因此,其正確的結(jié)構(gòu)如下:

那有人會有疑惑,為啥
RdyTab[i]->TCBPrev等等,這些為什么存在呢?
其實(shí)這個并不存在,這里單純指RdyTab[i]的內(nèi)存單元中,而我們需要使用RdyTab[i]->TCBPrev等等
時,必須先初始化RdyTab[i]的值,而這個RdyTab[i]->TCBPrev就是指初始化時指向內(nèi)存的首地址
偏移位置,這個工作是由編譯器完成的,如下圖所示!
顯然當(dāng)我們使用RdyTab[i]->TCBPrev時,其地址就是分配的結(jié)構(gòu)體所在的地址,而不是指針數(shù)組的地址。
-
內(nèi)存
+關(guān)注
關(guān)注
8文章
3159瀏覽量
75976 -
指針
+關(guān)注
關(guān)注
1文章
484瀏覽量
71630 -
數(shù)組
+關(guān)注
關(guān)注
1文章
420瀏覽量
27058 -
C指針
+關(guān)注
關(guān)注
0文章
10瀏覽量
6521
發(fā)布評論請先 登錄
C語言指針解析
基于C語言中指針的基本用法解析
C語言中的“二級指針”該如何理解
C語言二級指針的用法與原理
從最底層的內(nèi)存存儲空間開始帶你了解C語言指針
簡述C語言中什么是懸空指針和野指針
C語言指針詳細(xì)解析
C語言中的懸空指針和野指針是什么意思?
詳解C語言指針底層基本原理
C語言中一級指針、二級指針和三級指針
C++智能指針的底層實(shí)現(xiàn)原理

底層解析C指針(二)
評論