99精品伊人亚洲|最近国产中文炮友|九草在线视频支援|AV网站大全最新|美女黄片免费观看|国产精品资源视频|精彩无码视频一区|91大神在线后入|伊人终合在线播放|久草综合久久中文

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

一起來(lái)聊聊指針

dyquk4xk2p3d ? 來(lái)源:低并發(fā)編程 ? 2023-02-10 10:51 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

先說(shuō)內(nèi)存,內(nèi)存通常被嚴(yán)謹(jǐn)?shù)禺?huà)成下面這個(gè)樣子,一個(gè)下方是低地址上方是高地址的格子樓。

4128f5b8-a8dc-11ed-bfe3-dac502259ad0.png

但我今天換種畫(huà)法,畫(huà)成下面這個(gè)樣子。

41415b1c-a8dc-11ed-bfe3-dac502259ad0.png

每個(gè)格子代表內(nèi)存中的 1 個(gè)字節(jié)(8 位),格子上的數(shù)字就代表內(nèi)存地址,我也直接用 10 進(jìn)制來(lái)表示了,免得 16 進(jìn)制又算不明白了。

目前內(nèi)存是完全空的,格子里沒(méi)有任何內(nèi)容。

試想一下,如果你忘掉所有的語(yǔ)法規(guī)則和編程規(guī)范,你會(huì)如何描述對(duì)這些內(nèi)存格子的操作呢?

一、類型系統(tǒng)

很簡(jiǎn)單,往格子 3 處放個(gè)數(shù)字 29,往格子 6 處放個(gè)數(shù)字 38,就這么簡(jiǎn)單直接地描述即可。

416a61f6-a8dc-11ed-bfe3-dac502259ad0.png

但是這樣說(shuō)話太麻煩了,什么往格子 3 處放個(gè)數(shù)字 29 的,廢話太多,也不方便不講感情的計(jì)算機(jī)去理解。

那我們就定個(gè)指令,使用 mov $x, (y) 表示把數(shù)字 x 放入格子 y,如下:

mov$29,(3)
mov$38,(6)

這就表示剛剛說(shuō)的:

把數(shù)字29放入內(nèi)存格子3
把數(shù)字38放入內(nèi)存格子6

是不是太簡(jiǎn)單了?別急,好戲馬上開(kāi)始!

如果要把數(shù)字 999 放入內(nèi)存格子 8,該怎么辦呢?

由于 1 個(gè)格子表示 1 個(gè)字節(jié),只有 8 位,因此只能表示 256 個(gè)數(shù)字,要么是有符號(hào)的 -128 ~ 127,要么是無(wú)符號(hào)的 0 ~255,顯然數(shù)字 999 無(wú)法放在 1 個(gè)格子內(nèi),只能占用 2 個(gè)格子了。

那也好辦,就這么說(shuō),把數(shù)字 999 放入格子 8,連續(xù)占用兩個(gè)格子。

4180c892-a8dc-11ed-bfe3-dac502259ad0.png

但這樣,我們剛剛的 mov 指令就得改改了,不但要表示"存放"這個(gè)含義,還得表示占用了多少個(gè)格子。

我們用 movb 表示只占 1 個(gè)字節(jié),用 movw 表示占用 2 個(gè)字節(jié)。那么,剛剛的三個(gè)數(shù)字,就分別可以這樣用指令來(lái)表示了:

movb$29,(3)
movb$38,(6)
movw$999,(8)

含義就是:

把數(shù)字29放入內(nèi)存格子3,占1個(gè)字節(jié)
把數(shù)字38放入內(nèi)存格子6,占1個(gè)字節(jié)
把數(shù)字999放入內(nèi)存格子8,占2個(gè)字節(jié)

OK,既然有了 1 字節(jié)和 2 字節(jié)的的指令,不妨再設(shè)計(jì)下,用 movl 表示 4 字節(jié),movq 表示 8 字節(jié) ...

movb占用1字節(jié)
movw占用2字節(jié)
movl占用4字節(jié)
movq占用8字節(jié)

不知不覺(jué),類型系統(tǒng)就被你悄悄設(shè)計(jì)出來(lái)了!當(dāng)然,雖然這只是個(gè)半成品。

二、變量

你不斷地往不同格子里放數(shù)據(jù)。

比如我把我的年齡放在 11 號(hào)格子(占 1 字節(jié)),把我的月薪放在 14 號(hào)格子(占 4 字節(jié))。

41a56602-a8dc-11ed-bfe3-dac502259ad0.png

現(xiàn)在我們的內(nèi)存已經(jīng)非?;靵y了,你根本記不住原來(lái)的 3 號(hào)格子放的數(shù)據(jù)表示什么,11 號(hào)格子又表示什么,只能通過(guò)看數(shù)字知道 14 號(hào)格子里放的確實(shí)是我的月薪。這該怎么辦呢?

增加一層抽象嘛!我們給這些放了我們數(shù)據(jù)的格子,都貼上個(gè)標(biāo)簽,就可以不用再記那些無(wú)意義的格子編號(hào)了。

41c8ba4e-a8dc-11ed-bfe3-dac502259ad0.png

這樣一來(lái),其實(shí)我們也不再關(guān)心,這些標(biāo)簽到底在哪個(gè)格子里,只要給我找到格子把我的數(shù)據(jù)放進(jìn)去就可以了。

movb$29,a
movb$38,b
movw$999,c
movb$18,age
movl$2147483647,salary

當(dāng)然,我還需要再通過(guò)這個(gè)標(biāo)簽,把我剛剛放進(jìn)去的數(shù)據(jù)找出來(lái)。

這很簡(jiǎn)單,但存在一個(gè)問(wèn)題,放進(jìn)去的時(shí)候,我們可以通過(guò) movb,movw,movl 等知道占用多少個(gè)格子。而取出來(lái)的時(shí)候,標(biāo)簽上可沒(méi)有寫(xiě)這個(gè)數(shù)據(jù)占用了多少個(gè)格子,這是有問(wèn)題的。

因此,在定義這個(gè)標(biāo)簽時(shí),不能光取個(gè)名字,還需要有個(gè)信息就是,這個(gè)標(biāo)簽對(duì)應(yīng)的數(shù)據(jù),占了多少個(gè)格子。

我們就效仿剛剛的存放操作,也規(guī)定一系列單詞,來(lái)修飾這些標(biāo)簽,表示占用了多少個(gè)格子。

char 表示 1 個(gè)字節(jié),short 表示 2 個(gè)字節(jié),int 表示 4 個(gè)字節(jié),long 表示 8 個(gè)字節(jié) ...

41df303a-a8dc-11ed-bfe3-dac502259ad0.png

于是乎剛剛的 5 個(gè)數(shù)據(jù),就可以表示為如下指令:

chara=29;
charb=38;
shortc=999;
charage=18;
intsalary=2147483647;

行了,我也別藏著掖著了,相信大家也知道,這里就是 C 語(yǔ)言的寫(xiě)法,而剛剛那堆 mov 是匯編語(yǔ)言的寫(xiě)法。

這些 char a,char b,int salary 等,就是變量!記住,變量不但要有名字,還得有類型!

三、變量定義與賦值

其實(shí),剛剛的寫(xiě)法,是把變量的定義與賦值操作寫(xiě)在一行了。

比如有如下語(yǔ)句:

inta=1;

實(shí)際上是分成兩步的:

//變量的定義
inta;
//變量的賦值(此處也可以叫變量的初始化)
a=1;

其中變量的定義是為了方便程序員后面去用它,這部分不是給 CPU 看的。

420459dc-a8dc-11ed-bfe3-dac502259ad0.png

而變量的賦值才是真正在內(nèi)存中把數(shù)據(jù)放進(jìn)去,這部分才真正涉及 CPU 具體指令的執(zhí)行。

421c102c-a8dc-11ed-bfe3-dac502259ad0.png

也就是說(shuō),如果你僅僅定義了一個(gè)變量 int a; 但是沒(méi)有給它初始化的賦值操作,那么最終在 CPU 執(zhí)行指令的時(shí)候,這個(gè)定義根本就沒(méi)有任何體現(xiàn)。

四、指針

現(xiàn)在,讓我們把內(nèi)存清空,回到一開(kāi)始的那一片凈土上。

4230b0ea-a8dc-11ed-bfe3-dac502259ad0.png

我們來(lái)搞點(diǎn)花樣。我將我的密碼(1234)存儲(chǔ)在一個(gè) short a 中,假設(shè)這個(gè)變量 a 被放在了 6 號(hào)格子處。

4245232c-a8dc-11ed-bfe3-dac502259ad0.png

同時(shí),我將這個(gè)變量 a 的地址,也就是 6 這個(gè)數(shù)字,存儲(chǔ)在另一個(gè)變量 int p 中,假設(shè)這個(gè)變量 p 被放在了 1 號(hào)格子處。

4261eea8-a8dc-11ed-bfe3-dac502259ad0.png

這樣,我尋找我密碼的方式,就是先通過(guò) p 所在的內(nèi)存地址找到里面存的值,也就是 a 的內(nèi)存地址 6,再通過(guò) a 的內(nèi)存地址找到里面存的值,也就是我要找的密碼 1234。

我們可以用下面的代碼來(lái)表示剛剛的存放邏輯。

shorta=1234;
//假設(shè)a被放在了6號(hào)格子處
intp=6;

這里的 p 和 a 都是變量,只不過(guò),p 這個(gè)變量有點(diǎn)特殊,它里面存放的值是一個(gè)內(nèi)存地址,我們把 p 這個(gè)變量形象地稱為指針變量,簡(jiǎn)稱指針。

不過(guò),這樣有幾個(gè)問(wèn)題,我一個(gè)個(gè)來(lái)說(shuō)。

1. 取地址

首先,我們?cè)诰幋a階段,無(wú)法知道也無(wú)需知道變量 a 會(huì)存放在哪里,不然就失去了標(biāo)簽的含義,又回到了需要關(guān)心具體的內(nèi)存地址(也就是格子編號(hào))的時(shí)代了。

所以,我們應(yīng)該有個(gè)方法,來(lái)在編碼階段表示變量 a 的地址的含義,姑且就叫做 &a 吧。

那么我們的代碼,就可以優(yōu)化為:

shorta=1234;
//假設(shè)a的地址是6
//那么下面的p就等于6
intp=&a;

用圖來(lái)表示就是:

42792258-a8dc-11ed-bfe3-dac502259ad0.png

2. 指針變量本身的大小

視角放到這個(gè)變量 p 身上,雖然本質(zhì)上這個(gè)變量 p 里面存放的就是一個(gè)數(shù)值,假設(shè)是 6,但是它卻表示了一個(gè)內(nèi)存地址的值。

如果讓程序員隨便規(guī)定這個(gè)變量 p 的數(shù)據(jù)類型(也就是占多少個(gè)字節(jié)),那顯然容易出問(wèn)題。

比如內(nèi)存地址是 999,那么我用一個(gè) char 類型的變量 p 來(lái)存放它,就會(huì)有問(wèn)題。

我們?cè)诰幋a階段是無(wú)法確定一個(gè)變量的內(nèi)存地址是多少的,所以用什么類型的變量來(lái)存放它,也是無(wú)法判斷的。

所以,最穩(wěn)妥的辦法就是,用一個(gè)完全能容納所有內(nèi)存地址范圍的變量類型來(lái)存放指針變量。

我們姑且認(rèn)為我們是在一個(gè) 32 位的系統(tǒng)上,那么用一個(gè) 4 字節(jié)大小的變量來(lái)存放,就可以了。(當(dāng)然,實(shí)際上這取決于你的編譯器的位數(shù))

現(xiàn)在,我們的指針變量所占用的內(nèi)存大小,就是固定的 4 個(gè)字節(jié),也就是 4 個(gè)格子。

程序員無(wú)需也無(wú)法修改這個(gè)大小,那么我們就可以把 p 前面的數(shù)據(jù)類型去掉了。

shorta=1234;
p=&a;

3. 指針變量的類型

剛剛我們解決了指針變量本身所占用的內(nèi)存大小,但是還有一個(gè)問(wèn)題沒(méi)有解決,就是指針變量里存放的內(nèi)存地址處的變量的大小。

也就是說(shuō),上面的指針變量 p 里雖然存放了變量 a 的內(nèi)存地址 6,但是指針變量 p 卻沒(méi)有任何信息,來(lái)說(shuō)明內(nèi)存地址 6 處的變量,它的大小是多少。

假如,我們認(rèn)為內(nèi)存地址 6 處的變量是個(gè) char 類型,也就是只占用了一個(gè)字節(jié),那么顯然,會(huì)取出一個(gè)不符合預(yù)期的值。

4290faae-a8dc-11ed-bfe3-dac502259ad0.png

當(dāng)然,如果認(rèn)為 6 處的變量是個(gè) int 類型,占 4 個(gè)字節(jié),雖然數(shù)值上可能沒(méi)有問(wèn)題,但從某種程度上講也是不太符合預(yù)期的(假如 8 號(hào)和 9 號(hào)格子里有其他內(nèi)容,那就更不符合預(yù)期了)。

42a38354-a8dc-11ed-bfe3-dac502259ad0.png

所以,必須得完全按照變量本身的類型,也就是 short 類型來(lái)讀取此內(nèi)存地址處的值,才是正確的。

那我們應(yīng)該如何表示這個(gè)信息呢?即如何表示,變量 p 是一個(gè)指針,且這個(gè)指針里面存放的內(nèi)存地址處的變量的類型是 short。

很好辦,直接說(shuō)答案吧。

shorta=1234;
short*p=&a;

p 前面的 * 表示變量 p 是一個(gè)指針類型,再前面的 short 表示該指針指向的內(nèi)存地址處的變量,是個(gè) short 類型的變量。

當(dāng)然,更準(zhǔn)確的說(shuō)法是,指針 p 將會(huì)按照 short 類型的變量來(lái)讀取它指向的內(nèi)存,至于那里到底是什么,無(wú)所謂。

42c068ac-a8dc-11ed-bfe3-dac502259ad0.png

注意哦,這個(gè) short 并不是表示指針變量本身的大小占 2 個(gè)字節(jié),指針變量本身我們前面說(shuō)過(guò)了,就是固定的 4 字節(jié)大小。

不過(guò)總是這樣說(shuō)太繞口了,今后我們就說(shuō),變量 p 是個(gè) short * 類型的指針,就可以了。

用上面的圖形象地說(shuō)就是,右邊變量 a 藍(lán)色的填充,表示 a 是個(gè) short 類型,而外面的虛線框框,表示指針 p 按照 short 類型的變量來(lái)"解讀"內(nèi)存地址 6 處的數(shù)值。

兩者相匹配了,就是"正確"的編程代碼了。

當(dāng)然,這里的"正確",是說(shuō)給程序員聽(tīng)的,CPU 才不關(guān)心。

4. 指針?biāo)赶虻闹?/strong>

上面我們已經(jīng)可以獲得某個(gè)變量的地址,比如獲取 a 的地址就是:

&a

同時(shí)我們也可以定義一個(gè)指針變量,比如定義一個(gè) short * 類型的指針變量 p:

short*p;

并且,我們通過(guò)直接賦值操作,可以給指針變量進(jìn)行初始化:

p=&a;

當(dāng)然,上面的代碼也可以連起來(lái)寫(xiě),即指針變量 p 的定義與初始化寫(xiě)在同一行:

short*p=&a;

不過(guò),我們還沒(méi)有一個(gè)方法,來(lái)表示指針變量 p 所指向的那塊內(nèi)存。

那我們就發(fā)明一個(gè),比如想把 p 所指向的那塊內(nèi)存的值改為 999,可以這樣寫(xiě)。

*p=999;

這里的 * 就表示"指向"的含義,即 *p 不是說(shuō) p 這個(gè)變量的內(nèi)存地址,而是把 p 這個(gè)變量里存的內(nèi)容當(dāng)做內(nèi)存地址來(lái)看,指向這個(gè)內(nèi)存地址。

用圖表示就是:

42d6afd6-a8dc-11ed-bfe3-dac502259ad0.png

所以連起來(lái)一個(gè)完整的程序就是:

shorta=1234;
//指針的定義
short*p;
//指針的初始化,也即指針變量本身的值
p=&a;
//指針變量所指向的內(nèi)存地址的值
*p=999;

執(zhí)行過(guò)后,a 的值會(huì)變成 999,或者說(shuō) 6 號(hào)格子與 7 號(hào)格子里的值會(huì)變成 999。

5. 指針的加減

如果對(duì)一個(gè)普通變量 +1,比如說(shuō):

inta=1;
intb=a+1;

那顯然,b 的值應(yīng)該是 2,毫無(wú)疑問(wèn)。

但是如果對(duì)一個(gè)指針變量 +1,會(huì)怎么樣呢?

inta=1;
int*p=&a;
int*p2=p+1;

我們假設(shè)變量 a 放在了格子 1 處。

變量 a 的值是什么,以及變量 p 被放在了哪里,我們都不關(guān)心,就只盯著 p 的值看,顯然,一開(kāi)始的時(shí)候是 1。

(為方便演示,下面的圖直接表示 p 所指向的內(nèi)存地址,而不是 p 本身所在的內(nèi)存地址)

42eba436-a8dc-11ed-bfe3-dac502259ad0.png

我們先不考慮,p + 1 應(yīng)該是幾,如果讓你來(lái)設(shè)計(jì)這個(gè)語(yǔ)言,你覺(jué)得 p + 1 是幾比較好呢?

我認(rèn)為,只有兩種較為合理的設(shè)計(jì)。

第一種,p + 1 就等于 2,就簡(jiǎn)簡(jiǎn)單單當(dāng)做數(shù)值進(jìn)行加法運(yùn)算而已。

4309aad0-a8dc-11ed-bfe3-dac502259ad0.png

第二種,p + 1 等于 5,即跨過(guò)一個(gè) p 所指向的內(nèi)存單元的數(shù)據(jù)類型的大小,也就是 4 字節(jié)的 int。

43264744-a8dc-11ed-bfe3-dac502259ad0.png

你覺(jué)得哪種比較合理呢?

那顯然是第二種嘛!不然和普通變量有啥區(qū)別了,你既然設(shè)計(jì)出了指針變量這個(gè)玩意,就需要讓它發(fā)揮點(diǎn)方便程序員的作用,這才是你設(shè)計(jì)它的真正目的。

當(dāng)然你不服,你就想讓這個(gè) int * 類型的指針變量,就真真正正在數(shù)值上只 +1,也就是讓 p 等于 2,該怎么辦呢?

很簡(jiǎn)單,分成三步就好了:

第一步,把 int * 類型的 p 強(qiáng)轉(zhuǎn)為 char * 類型的 p。

4346e68e-a8dc-11ed-bfe3-dac502259ad0.png

第二步,p + 1。

4364550c-a8dc-11ed-bfe3-dac502259ad0.png

第三步,再把 char * 類型的 p 強(qiáng)轉(zhuǎn)為 int * 類型。

437856e2-a8dc-11ed-bfe3-dac502259ad0.png

完事!用代碼表示就是:

p=(int*)((char*)p+1);

你會(huì)看到,C 語(yǔ)言項(xiàng)目中經(jīng)常使用這樣的玩法。

當(dāng)然,你這一頓花里胡哨的操作,在 CPU 眼里,就是對(duì)一個(gè)內(nèi)存地址處的值簡(jiǎn)簡(jiǎn)單單地 +1 而已。

五、指針的本質(zhì)

我們看上面的一張圖:

42c068ac-a8dc-11ed-bfe3-dac502259ad0.png

其實(shí),別看上面又 short * p 又 short a 的,這是給程序員和編譯器看的。

在 CPU 眼里,根本沒(méi)有這些眼花繚亂的標(biāo)簽,以及五花八門(mén)的解讀,就是 0 ~ 4 號(hào)格子里存了個(gè)數(shù)字 6,然后 6 ~ 7 號(hào)格子里存了個(gè)數(shù)字 1234,僅此而已。

更進(jìn)一步講,其實(shí)就只是 1 號(hào)格子里存儲(chǔ)了數(shù)字 6(234 號(hào)格子是空的),6 號(hào)格子里存儲(chǔ)了數(shù)字 12,7 號(hào)格子里存儲(chǔ)了數(shù)字 34。

439838e0-a8dc-11ed-bfe3-dac502259ad0.png

(當(dāng)然實(shí)際得轉(zhuǎn)換成二進(jìn)制,再結(jié)合大端序還是小端序來(lái)看哈,我這里就是簡(jiǎn)單直觀告訴大家 CPU 才不管那么多,就一個(gè)格子一個(gè)格子的放數(shù)字就完事了)

所以,我們經(jīng)常聽(tīng)書(shū)上講,讓大家一定要記住,指針變量中只能存放地址,不要將一個(gè)整數(shù)或任何其他非地址類型的數(shù)據(jù)賦給一個(gè)指針變量了。

這種說(shuō)法就非常別扭,很多書(shū)上,即想講清楚指針的本質(zhì),又想講清楚指針的注意事項(xiàng),混雜在一起,讓讀者即沒(méi)有搞清楚指針的本質(zhì),又不知道指針的注意事項(xiàng)。

真糾結(jié)!

說(shuō)實(shí)話,就光看書(shū)而沒(méi)有經(jīng)過(guò)大量 C 語(yǔ)言的實(shí)踐,誰(shuí)能記得住或者理解透徹那些注意事項(xiàng)。而經(jīng)過(guò)大量 C 語(yǔ)言實(shí)踐的人,指針早就融入進(jìn)血液中了,誰(shuí)還來(lái)看你講指針的本質(zhì)?所以說(shuō),這塊我覺(jué)得非常之矛盾。

實(shí)際上,指針變量的本質(zhì)和普通變量是一樣的:

普通變量,寫(xiě)個(gè) short a,是在告訴編譯器,當(dāng)我 a = 1 時(shí),你給我找到一塊 2 字節(jié)的內(nèi)存,把 1 填充進(jìn)去。

指針變量,寫(xiě)個(gè) short * p,是在告訴編譯器兩件事情:

當(dāng)我 p = xxx 時(shí),你給我找到一塊 4 字節(jié)的內(nèi)存(我們假設(shè)指針本身的大小固定 4 字節(jié)),把 xxx 填充進(jìn)去,這就和普通變量完全一樣;

當(dāng)我 *p = yyy 時(shí),你給我找到 xxx 內(nèi)存地址,并且按照 short 類型也就是 2 字節(jié)大小,把 yyy 填充到這里。

43aa69c0-a8dc-11ed-bfe3-dac502259ad0.png

所以,誰(shuí)說(shuō)不能把一個(gè)整型變量賦給指針了,我這不就把一個(gè)整型變量 xxx 賦給指針 p 了么,我賦值的時(shí)候就說(shuō)它是整型變量了,怎么的吧?

但是我用它的時(shí)候,我 *p 又把 xxx 看做是一個(gè)內(nèi)存地址了,就去找內(nèi)存 xxx 的地方,又怎么的吧?

用代碼來(lái)表示就是:

我強(qiáng)行把一個(gè)整型數(shù)值 6 賦值給指針變量 p,然后 *p 去訪問(wèn)內(nèi)存地址 6 并修改那個(gè)地方的值:

int*p=6;
*p=999;

我還可以把一個(gè)地址值,強(qiáng)行賦值給一個(gè)普通變量:

inta=1;
intb=&a;

這時(shí)普通變量 b 里面存儲(chǔ)著 a 的地址,我 *b 也同樣可以訪問(wèn)到 a 并修改它的值:

*b=999;

當(dāng)然如果你真這么寫(xiě)編譯器會(huì)報(bào)錯(cuò),但沒(méi)關(guān)系,我們可以先把普通變量 b 強(qiáng)轉(zhuǎn)為指針變量,然后再 * 它:

*(int*)b=999;

你還可以玩些更花哨的,先 & 取地址,再 * 取值,雖然沒(méi)啥用:

*((int*)*(&p))=999;

假如 a 的地址是 6 的話,其實(shí)你這些花里胡哨的操作,最后到人家 CPU 眼里,就是一條簡(jiǎn)單的指令:

movl$999,(6)

就是想把 999 放在 6 號(hào)格子嘛!

所以,不要把指針想得多么復(fù)雜和神圣,它就是方便了程序員編程,同時(shí)告訴編譯器應(yīng)該怎么編譯成最終的指令。

你寫(xiě)了個(gè) *p,就是把 p 的值當(dāng)做內(nèi)存地址去訪問(wèn),在匯編語(yǔ)言層面就是加了個(gè)括號(hào):

(p)

你寫(xiě)了個(gè) &a,就是取出變量 a 的內(nèi)存地址,在匯編語(yǔ)言層面就是 lea 指令:

leaa,xxx

你如果寫(xiě)了個(gè) ***p 那就是,相當(dāng)于加了三次括號(hào):

(((p)))

當(dāng)然啦,以上都是方便理解的偽指令,具體落實(shí)到真正的匯編語(yǔ)言,你就會(huì)發(fā)現(xiàn)指針就是個(gè)工具人而已。

六、寫(xiě)在最后

至此,今天的內(nèi)容就講完了。

我們從最開(kāi)始的內(nèi)存格子出發(fā),逐漸推導(dǎo)出類型系統(tǒng)和變量的作用,進(jìn)而再引出本質(zhì)上和普通變量沒(méi)有任何區(qū)別的指針變量,最后再推導(dǎo)出指針變量相關(guān)的操作,帶你看清了指針的本質(zhì)。

42c068ac-a8dc-11ed-bfe3-dac502259ad0.png

你不要去記本文的知識(shí)點(diǎn),重在整個(gè)推導(dǎo)的過(guò)程,要去理解指針想解決的問(wèn)題是什么,它的合理性在哪,哪一部分信息是給程序員和編譯器看的,哪一部分操作最終又是真正落實(shí)到 CPU 指令的,這些才是關(guān)鍵。

當(dāng)然,我還是給你簡(jiǎn)單總結(jié)下知識(shí)點(diǎn)相關(guān)的部分,其實(shí)簡(jiǎn)單說(shuō),就這么幾件事。

定義一個(gè)指針:

int*p;

賦值或初始化一個(gè)指針:

p=&a;

修改指針的內(nèi)容:

*p=999;

指針的加減(其實(shí)到后面講的數(shù)組才有價(jià)值):

p=p+1;

完事,就這些!







審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • cpu
    cpu
    +關(guān)注

    關(guān)注

    68

    文章

    11076

    瀏覽量

    217001
  • C語(yǔ)言
    +關(guān)注

    關(guān)注

    180

    文章

    7632

    瀏覽量

    141624
  • 匯編語(yǔ)言
    +關(guān)注

    關(guān)注

    14

    文章

    412

    瀏覽量

    36857
  • mov指令
    +關(guān)注

    關(guān)注

    0

    文章

    3

    瀏覽量

    2032

原文標(biāo)題:你管這破玩意叫指針?

文章出處:【微信號(hào):良許Linux,微信公眾號(hào):良許Linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    尋開(kāi)發(fā)伙伴 一起搞細(xì)胞電阻儀,有興趣的朋友來(lái)聊聊!

    尋開(kāi)發(fā)伙伴 一起搞細(xì)胞電阻儀,有興趣的朋友來(lái)聊聊!
    發(fā)表于 07-10 15:51

    讓我們一起來(lái)寫(xiě)makefile

    大家一起來(lái)學(xué)哈
    發(fā)表于 03-14 00:04

    一起來(lái)學(xué)習(xí)FPGA,歡迎愛(ài)好者加入QQ群199362558

    一起來(lái)學(xué)習(xí)FPGA,F(xiàn)PGA學(xué)習(xí)小組開(kāi)始招收成員,歡迎愛(ài)好者加入 FPGA技術(shù)交流群:199362558
    發(fā)表于 02-27 15:25

    一起學(xué)FPGA

    各位,個(gè)人學(xué)多沒(méi)意思,也效率低。有沒(méi)有想一起學(xué)學(xué)的,最好也是同城的沒(méi)事還可以出來(lái)聊聊,交個(gè)朋友。 歡迎各種菜鳥(niǎo)、大神。本人有點(diǎn)菜,呵呵。 QQ 245966960
    發(fā)表于 11-10 13:35

    Abdroid論壇的帖子 資料好少,做個(gè)榜樣,大家一起來(lái)瘋狂and...

    Abdroid論壇的帖子 資料好少,做個(gè)榜樣,大家一起來(lái)瘋狂android吧
    發(fā)表于 04-07 13:33

    【招募帖】有人對(duì)智能硬件感興趣嗎,一起來(lái)交流吧。

    ,并請(qǐng)反饋產(chǎn)品評(píng)測(cè)報(bào)告或試用體驗(yàn)。大致情況就是這樣,不知道有人有興趣嗎?一起來(lái)聊聊吧,有興趣的可以私信我或是加我QQ:632170494 會(huì)再和您詳說(shuō)的。
    發(fā)表于 03-23 10:52

    一起來(lái)討論吧

    一起來(lái)討論吧
    發(fā)表于 10-24 10:35

    一起來(lái)論壇學(xué)習(xí)吧

    一起來(lái)論壇學(xué)習(xí)吧
    發(fā)表于 10-24 10:39

    一起來(lái)學(xué)習(xí)嗎

    一起來(lái)學(xué)習(xí)嗎
    發(fā)表于 11-10 15:02

    DMA有何功能?當(dāng)多個(gè)DMA請(qǐng)求一起來(lái)怎么辦

    DMA有哪些功能呢?與DMA相關(guān)庫(kù)函數(shù)有哪些呢?DMA有何功能?當(dāng)多個(gè)DMA請(qǐng)求一起來(lái)怎么辦?
    發(fā)表于 01-27 07:11

    一起來(lái)認(rèn)識(shí)深入了解水銀

    一起來(lái)認(rèn)識(shí)深入了解水銀    汞在常溫下呈液態(tài),
    發(fā)表于 10-23 09:22 ?2459次閱讀

    一起來(lái)認(rèn)識(shí)廢舊電池的危害

    一起來(lái)認(rèn)識(shí)廢舊電池的危害  當(dāng)廢舊電池被當(dāng)做垃圾丟棄、進(jìn)入大自然之后,其中的重金屬并不能被生物降解,對(duì)環(huán)境造成嚴(yán)重的污染。據(jù)統(tǒng)
    發(fā)表于 11-02 16:53 ?1836次閱讀

    我們一起來(lái)實(shí)現(xiàn)氮化鎵的可靠運(yùn)行

    我們一起來(lái)實(shí)現(xiàn)氮化鎵的可靠運(yùn)行
    發(fā)表于 11-03 08:04 ?2次下載
    我們<b class='flag-5'>一起來(lái)</b>實(shí)現(xiàn)氮化鎵的可靠運(yùn)行

    【直播來(lái)襲】OneOS系統(tǒng)教程全面上線,邀您和ST、OneOS一起來(lái)學(xué)習(xí)啦!

    【直播來(lái)襲】OneOS系統(tǒng)教程全面上線,邀您和ST、OneOS一起來(lái)學(xué)習(xí)啦!
    的頭像 發(fā)表于 04-22 14:33 ?968次閱讀
    【直播來(lái)襲】OneOS系統(tǒng)教程全面上線,邀您和ST、OneOS<b class='flag-5'>一起來(lái)</b>學(xué)習(xí)啦!

    一起來(lái)學(xué)5G終端射頻標(biāo)準(zhǔn)(EVM均衡器頻譜平坦度-2)

    一起來(lái)學(xué)5G終端射頻標(biāo)準(zhǔn)(EVM均衡器頻譜平坦度-1)中的測(cè)試圖例,這里補(bǔ)下:01—EVM均衡器系數(shù)的計(jì)算由上圖紅框可知,結(jié)果由四部分組成,那么這四個(gè)結(jié)果是如何計(jì)算的呢?我們?cè)?b class='flag-5'>一起來(lái)
    的頭像 發(fā)表于 03-20 14:05 ?2854次閱讀
    <b class='flag-5'>一起來(lái)</b>學(xué)5G終端射頻標(biāo)準(zhǔn)(EVM均衡器頻譜平坦度-2)