關於contain_of的理解。
核心中有這樣的乙個巨集:
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
作用是這樣的:如果你獲得了乙個大結構體裡面的乙個成員的指標,那麼通過這個巨集,你就能獲得這個結構體的指標。
假設存在這麼乙個結構體:
struct student;
這裡的type1,2,3就是我們平時常見的int,char之類的。之所以不寫具體的型別是避免還要考慮記憶體中位元組對齊等問題。
現在用這個結構體來宣告乙個物件:struct student demo;
那麼在記憶體中demo的分布應該是這樣的:
—————–0x6000
a —————- 0x6008
b —————–0x600a
c —————-0x600e
上面的記憶體位址分布都是我隨意寫的,因為我並沒有具體type1.2.3是什麼型別。
那麼container_of巨集的三個引數分別代表什麼呢?
ptr :指向結構體內成員的指標,比如type2 * pointer=&b
type :這個結構體型別 ,比如 struct student
member:結構體成員名字,比如 b
代入巨集看看是什麼樣的?
const typeof( (( struct student*)0)->b) *__mptr = (pointer); \
( struct student*)( (char *)__mptr - offsetof( struct student,b) );})
初步的替換就是這樣,但是這個裡面還有巨集offsetof(struct student,b),暫且不看先。
const typeof( (( struct student*)0)->b) *__mptr = (pointer); 這句**的作用是宣告了乙個指標__mptr。typeof的作用是獲取變數的型別,所以__mptr的型別就是type2。然後把pointer指標的值賦給它,其實就是兩個指標指向同一塊記憶體,就是指向0x6008。
下面展開offsetof( struct student,b) 看看是什麼?
替換後得到:
(struct student*)0)這句話的意思是把student結構體的起始位址強制制定為0,那麼b的位址就是相對0位址的偏移量,然後取址,在上圖中就是0x0008.
回看(char )__mptr這句話的意思:把這個指標強制型別轉換為(char),也就是這個指標現在是位元組指標了。為什麼這麼做呢?因為記憶體儲存的最基本單位都是位元組。這樣的轉換可以用來做加減法十分方便。
綜上所述,0x6008-0x0008=0x6000.這個位址也就是demo結構體的起始位址了,然後轉換為struct student型別的指標。
關於this的理解
this是乙個關鍵字,它不允許更改或者賦值,任何函式只要作為方法呼叫時實際上都會傳入乙個隱式的實參 這個實參是乙個物件,方法呼叫的母體就是這個物件 this 1.當函式作為乙個方法呼叫時 呼叫的母體就是該物件 2.當作普通函式呼叫時 呼叫的母體是window 3.閉包裡面的this var obj ...
關於getchar的理解
最近在看k r的c語言程式設計,看到有個地方很不是理解,查閱了較多的資料後才恍然大悟,記錄一下先。程式是比較常見的從控制台獲得一行,並返回這行的長度。程式如下 int getline char s,int lim 開始對getchar這個函式不是很理解,為什麼每次迴圈都讀取乙個 char 既然我是個...
關於委託的理解
學習c 有一段時間了,對委託一直不是很理解,試著說一下。委託是對方法的傳遞呼叫,即把方法像引數一樣傳遞。我們知道,方法具有引數。這個引數可以是基本資料型別,如int,double等,也可以是引用型別 即類 包括系統自帶的和自定義的。例如,我們有個方法add,它的引數是兩個int型別整數。int ad...