編程代碼
新聞詳情

「C++」讀懂指針與内存

發布時(shí)間:2021-01-18 09:08:08 浏覽次數:2826

C和(hé / huò)C++最強大(dà)的(de)地(dì / de)方在(zài)哪裏呢?就(jiù)是(shì)指針對内存的(de)操作。有了(le/liǎo)指針我們才可以(yǐ)在(zài)代碼内存裏自由飛翔,想玩哪裏玩哪裏,想變什麽變什麽。


内存
首先我們聊聊什麽是(shì)内存(我們以(yǐ)32位程序模型爲(wéi / wèi)例)。對于(yú)一(yī / yì /yí)個(gè)進程來(lái)說(shuō),内存可以(yǐ)理解成一(yī / yì /yí)連串的(de)帶編号的(de)存儲區域。

每個(gè)進程都映射一(yī / yì /yí)段連續的(de)虛拟内存地(dì / de)址(不(bù)是(shì)内存的(de)真實物理地(dì / de)址,隻是(shì)一(yī / yì /yí)個(gè)編号,物理内存地(dì / de)址可以(yǐ)不(bù)連續)。

「C++」讀懂指針與内存

每個(gè)格子(zǐ)我們理解爲(wéi / wèi)一(yī / yì /yí)個(gè)字節,也(yě)就(jiù)是(shì)一(yī / yì /yí)個(gè)byte或者說(shuō)一(yī / yì /yí)個(gè)unsigned char。


而(ér)指針其實就(jiù)是(shì)一(yī / yì /yí)個(gè)數字,記錄的(de)就(jiù)是(shì)内存的(de)地(dì / de)址,也(yě)就(jiù)是(shì)我們标記的(de)每個(gè)小格子(zǐ)的(de)數字編号。

在(zài)32位系統的(de)時(shí)候,指針占4個(gè)字節,能表示的(de)數字最大(dà)值是(shì)4294967295。

(64位程序指針占8個(gè)字節,所以(yǐ)能使用的(de)内存空間就(jiù)很大(dà))

「C++」讀懂指針與内存

「C++」讀懂指針與内存

将4294967295個(gè)字節轉換G單位大(dà)概就(jiù)是(shì)4G。所以(yǐ)32位程序能用的(de)最大(dà)内存空間就(jiù)是(shì)4G。其中0到(dào)3G是(shì)用戶空間,3G到(dào)4G是(shì)内核空間,我們在(zài)實際使用32位程序時(shí)候,大(dà)概也(yě)就(jiù)能操作到(dào)1.7G左右的(de)内存,超過這(zhè)個(gè)量再分配内存基本上(shàng)程序就(jiù)崩潰了(le/liǎo)。


程序的(de)内存區域大(dà)概分了(le/liǎo)如圖六塊,其中堆和(hé / huò)棧是(shì)根據實際運行情況擴展使用内存區域。

「C++」讀懂指針與内存

來(lái)來(lái)來(lái)。。我們寫段代碼驗證下,都用int變量,偏移量是(shì)4個(gè)字節,方便查看。

看看運行結果,内存地(dì / de)址就(jiù)是(shì)這(zhè)樣按照區域分配的(de)。

「C++」讀懂指針與内存

「C++」讀懂指針與内存

指針

明白了(le/liǎo)内存,我們就(jiù)來(lái)玩玩指針,看他(tā)怎麽個(gè)自由飛翔。

先上(shàng)一(yī / yì /yí)段樸實的(de)代碼:

「C++」讀懂指針與内存

運行結果是(shì)這(zhè)樣的(de):

「C++」讀懂指針與内存

讓我們來(lái)分析下這(zhè)段代碼吧。


爲(wéi / wèi)了(le/liǎo)方便使用結構體倒騰,我這(zhè)裏都用的(de)是(shì)4倍體的(de)變量,而(ér)且把double放在(zài)了(le/liǎo)第一(yī / yì /yí)個(gè)。關于(yú)結構體排列問題有機會我再寫寫。反正這(zhè)裏呢,就(jiù)按照這(zhè)幾個(gè)位置排列内存了(le/liǎo)。


首先我們整了(le/liǎo)一(yī / yì /yí)個(gè)100字節的(de)内存,神馬都沒有,然後通過指針和(hé / huò)偏移量,我們可以(yǐ)跳轉到(dào)内存任意位置,并且可以(yǐ)把那個(gè)位置解釋成任意類型。所以(yǐ)指針可以(yǐ)是(shì)8字節的(de)double類型,也(yě)可以(yǐ)是(shì)4字節的(de)int和(hé / huò)float類型,然後對該類型直接賦值。

最後,我們直接來(lái)個(gè)風騷操作,把這(zhè)段内存強制當成結構體類型的(de)指針,然後因爲(wéi / wèi)位置能對上(shàng),所以(yǐ)結構體内的(de)成員變量就(jiù)都對應上(shàng)了(le/liǎo)。


然後我們再來(lái)玩一(yī / yì /yí)玩快樂指針的(de)遊戲,依然使用剛才内存倒騰過的(de)區域。

「C++」讀懂指針與内存

這(zhè)裏p指向了(le/liǎo)b變量的(de)位置,此時(shí)我們可以(yǐ)把p當成一(yī / yì /yí)個(gè)int數組,所以(yǐ)p[3]就(jiù)是(shì)該數組第四個(gè)元素,也(yě)就(jiù)是(shì)變量e。

「C++」讀懂指針與内存

這(zhè)裏p+2表示按照指針類型移動2個(gè)位置,int是(shì)4個(gè)字節,所以(yǐ)内存上(shàng)總共移動8個(gè)字節,到(dào)了(le/liǎo)d的(de)位置,雖然位置對了(le/liǎo),但是(shì)d不(bù)是(shì)一(yī / yì /yí)個(gè)int類型,按照int去解釋是(shì)錯誤的(de)。所以(yǐ)我們把類型解釋成float。

「C++」讀懂指針與内存

當然因爲(wéi / wèi)float也(yě)是(shì)4個(gè)字節,所以(yǐ)我們可以(yǐ)p[2]直接取到(dào)d位置的(de)值,此時(shí)這(zhè)裏是(shì)解釋出(chū)來(lái)的(de)int值是(shì)錯誤的(de),然後我們取地(dì / de)址變成指針,再強轉成float指針,再取值,結果一(yī / yì /yí)樣。


記住。。。指針就(jiù)是(shì)地(dì / de)址數字而(ér)已,可以(yǐ)轉成任意類型,可以(yǐ)按照指針對應類型的(de)大(dà)小做加減法偏移,也(yě)可以(yǐ)按照指針對應類型的(de)大(dà)小做數組偏移。

在(zài)線客服 雙翌客服
客服電話
  • 0755-23712116
  • 13310869691