對(duì)[C/C++]指針/引用和內(nèi)存分配的總結(jié)

C/C++ 系統(tǒng) 內(nèi)存分布圖

屏幕快照 2019-08-13 上午11.07.25.png

變量和內(nèi)存地址的關(guān)系

計(jì)算機(jī)存儲(chǔ)器位置具有地址并保存內(nèi)容蔚万。地址是一個(gè)數(shù)字(通常用十六進(jìn)制表示)岭妖,這對(duì)程序員來(lái)說(shuō)很難直接使用。通常笛坦,每個(gè)地址位置保持8位(即1字節(jié))數(shù)據(jù)区转。程序員完全可以解釋數(shù)據(jù)的含義,例如整數(shù)版扩,實(shí)數(shù)废离,字符或字符串。

為了減輕使用數(shù)字表示的內(nèi)存地址給程序員解釋數(shù)據(jù)的編程負(fù)擔(dān)礁芦,早期的編程語(yǔ)言(如C)引入了變量的概念蜻韭。變量就是為存儲(chǔ)特定類型值的內(nèi)存地址命令了一個(gè)對(duì)人具有可讀性的標(biāo)識(shí)符。變量名(或標(biāo)識(shí)符)附加到特定的地址中柿扣。tong此外肖方,類型(例如int,double未状,char)與數(shù)據(jù)內(nèi)容長(zhǎng)度相關(guān)聯(lián)俯画,以便于解釋數(shù)據(jù)。

每個(gè)地址位置通常保持8位(即1字節(jié))數(shù)據(jù)司草。 4字節(jié)的int值占用4個(gè)內(nèi)存位置艰垂。 32位系統(tǒng)通常使用32位地址泡仗。要存儲(chǔ)32位地址,需要4個(gè)存儲(chǔ)單元猜憎。

下圖說(shuō)明了計(jì)算機(jī)的內(nèi)存地址,數(shù)據(jù)內(nèi)容,變量的名稱娩怎,類型和程序員使用的值之間的關(guān)系。


MemoryAddressContent.png

引用(reference)

C++ Primer這本書(shū)并沒(méi)有對(duì)reference類型在內(nèi)存管理方面給出一個(gè)明確的結(jié)論.因此以下從其他資料摘錄了相關(guān)的定義

引用不是對(duì)象; 它們不一定占用存儲(chǔ)空間胰柑,盡管如果有必要實(shí)現(xiàn)所需的語(yǔ)義截亦,編譯器可以分配存儲(chǔ)空間(例如,引用類型的非靜態(tài)數(shù)據(jù)成員通常會(huì)增加類的大小以存儲(chǔ)存儲(chǔ)器地址所需的數(shù)量)柬讨。
--摘錄自https://en.cppreference.com/w/cpp/language/reference

根據(jù)Bjarne Stroustrup的說(shuō)法崩瓤,引用變量大多數(shù)時(shí)間都是優(yōu)化的,并且沒(méi)有為引用創(chuàng)建變量姐浮。 但是谷遂,在某些無(wú)法優(yōu)化引用變量的情況下,它實(shí)現(xiàn)為指向原始對(duì)象的4字節(jié)指針卖鲤。因此肾扰,在大多數(shù)情況下,編譯器在涉及引用的語(yǔ)句中使用實(shí)際對(duì)象而不是引用變量蛋逾。
--摘錄自《The C++ Programming Language》

對(duì)引用的總結(jié)

  • 在C++中所謂的引用"reference"就是左值引用,可以比喻為對(duì)象(變量)起一個(gè)別名集晚。
  • 初始化完成,引用將和它的初始值對(duì)象綁定在一起,無(wú)法重新綁定到另一個(gè)對(duì)象(變量)
  • 引用不是對(duì)象,沒(méi)有實(shí)際地址,所以“不存在引用的引用或指向某個(gè)引用的指針”区匣。
  • 引用只能綁定到對(duì)象,無(wú)法綁定到具體的字面量或某個(gè)表達(dá)式的計(jì)算結(jié)果
  • 對(duì)引用變量取址(&)操作,大部份情況下引用變量所指向的對(duì)象的內(nèi)存地址偷拔。特殊情況下,引用變量會(huì)被編譯器識(shí)別為一個(gè)4字節(jié)長(zhǎng)度的指針。
    如圖所示:0x????????表示引用不一定會(huì)產(chǎn)生內(nèi)存分配


    屏幕快照 2019-08-13 上午11.44.35.png

指針

《征服C指針》這本書(shū)對(duì)指針剖析十分透徹亏钩,以下對(duì)C指針的理解方法大部份源于該書(shū)莲绰。

#include <iostream>

int **pp=nullptr;

int main(int argc, char const *argv[])
{
    
    int b=734;

    int *p=&b;
    pp=&p;
    
    std::cout<<"variable b address:"<<p<<std::endl;
    std::cout<<*"pointer p address:"<<pp<<std::endl;
    std::cout<<*"pointer pp address:"<<&pp<<std::endl;
    return 0;
}

如圖所示所示指針關(guān)系


屏幕快照 2019-08-13 下午4.27.38.png

如何正確解讀函數(shù)指針

用英文來(lái)解讀指針,看如下幾個(gè)經(jīng)典的例子

int (*my_func)()
英文的閱讀順序:
  1. 首先著眼于標(biāo)識(shí)符(變量名或者函數(shù)名)姑丑。
  2. 從距離標(biāo)識(shí)符最近的地方開(kāi)始蛤签,依照優(yōu)先順序解釋派生類型(指針、數(shù)組和函數(shù))栅哀。優(yōu)先順序說(shuō)明如下震肮,
    1. 用于整理聲明內(nèi)容的括弧
    2. 用于表示數(shù)組的[],用于表示函數(shù)的()
    3. 用于表示指針的 *
  3. 解釋完成派生類型留拾,使用“of”戳晌、“to”、“returning”將它們連接起來(lái)痴柔。
  4. 最后沦偎,追加數(shù)據(jù)類型修飾符(在左邊,int、double 等)豪嚎。


    以下該圖來(lái)自《征服c指針》的3.4章節(jié)

特殊的指針

  1. 空指針 c中為NULL,C++為nullptr
  2. void指針,也稱為萬(wàn)能指針,任何類型的指針都可以賦值給void指針
  3. 指向常量的指針:不能用指向常量的指針改變其所指對(duì)象的值鸿捧。
    • 僅有指向常量的指針才能存放常量對(duì)象的地址。
    • 指向常量的指針允許指向一個(gè)非常量的對(duì)象疙渣。
      const double pi=3.14 //pi是個(gè)常量
    
      //錯(cuò)誤:&p的指針類型是【double *p】和 【const double *p】不匹配
      double *p=&pi;       
      //正確:指針的類型與pi的指針類型【const double *p】匹配
      const double *pt=&pi;
      //錯(cuò)誤:不能修改【指向常量的指針】所指向的對(duì)象
      *pt=42.3; 
      double dq=222.3;
      //正確:指向常量的指針允許指向一個(gè)非常量的對(duì)象。
      pt=&dq;
    
  4. 常量指針
    • 該指針存放其指向變量的地址值一經(jīng)初始法,就不能再改變.
    • 常量指針?biāo)傅淖兞坎皇浅A?
      示例1
     int a=123;
     int *const pr=&a;   //后續(xù)一直指向變量a,無(wú)法修改.
    
    示例2
     const int c=777; //對(duì)應(yīng)的指針類型【const int *p】
     //錯(cuò)誤:pr的指針類型【*const pr】和【const int *p】不匹配
     int *const pr=&c;  
    

5.指向常量的常量指針

  • 該指針存放其指向變量的地址值一經(jīng)初始法,就不能再改變.
  • 無(wú)法通過(guò)指向常量的常量指針修改所指的變量值,即便指向的值是非常量對(duì)象.
       const int c=77;
       int b=734;
       const int *const pr1=&c;
       const int *const pr2=&b;
       //錯(cuò)誤:具體原因查看第二小點(diǎn)
      *pr1=723;
       //但變量修改自身,和指向常量的常量指針沒(méi)有關(guān)系
       c=1024;  
    
  1. 各種特殊指針的對(duì)比總結(jié)


    知識(shí)點(diǎn)匯總

指向指針的引用

引用不是一個(gè)對(duì)象堆巧,因此不能定義指向引用的指針妄荔,但指針是一個(gè)對(duì)象,所以可以定義對(duì)指針的引用。

int i=42;
int *p;   //p is pointer to int 或p是一個(gè)指向int類型的指針
int *&r=p; 
//英文解讀法:r is  a reference **binding** pointer of int
//中文閱讀法: "r是綁定int指針的引用"
r=&i

要理解r 的類型到底是千| 么谍肤,最簡(jiǎn)單的辦法是從右向左閱讀r 的定義啦租。離變量名最近的符號(hào)( 此例中是&r 的符號(hào)&) 對(duì)變量的類型有最直接的影響,因此r 是一個(gè)引用荒揣。聲明符的其余部分用以確定r 引用的類型是什么篷角,此例中的符號(hào)* 說(shuō)明E 引用的是一個(gè)指針。最后系任,聲明的基本數(shù)據(jù)類型部分指出r 引用的是一個(gè)工nt 指針恳蹲。 ---《摘錄自c++ Primer 第五版》

yu

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市俩滥,隨后出現(xiàn)的幾起案子嘉蕾,更是在濱河造成了極大的恐慌,老刑警劉巖霜旧,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件错忱,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡挂据,警方通過(guò)查閱死者的電腦和手機(jī)以清,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)崎逃,“玉大人掷倔,你說(shuō)我怎么就攤上這事』橥眩” “怎么了今魔?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)障贸。 經(jīng)常有香客問(wèn)我错森,道長(zhǎng),這世上最難降的妖魔是什么篮洁? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任涩维,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘瓦阐。我一直安慰自己蜗侈,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布睡蟋。 她就那樣靜靜地躺著踏幻,像睡著了一般。 火紅的嫁衣襯著肌膚如雪戳杀。 梳的紋絲不亂的頭發(fā)上该面,一...
    開(kāi)封第一講書(shū)人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音信卡,去河邊找鬼隔缀。 笑死,一個(gè)胖子當(dāng)著我的面吹牛傍菇,可吹牛的內(nèi)容都是我干的猾瘸。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼丢习,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼牵触!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起咐低,我...
    開(kāi)封第一講書(shū)人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤荒吏,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后渊鞋,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體绰更,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年锡宋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了儡湾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡执俩,死狀恐怖徐钠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情役首,我是刑警寧澤尝丐,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站衡奥,受9級(jí)特大地震影響爹袁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜矮固,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一失息、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦盹兢、人聲如沸邻梆。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)浦妄。三九已至,卻和暖如春见芹,著一層夾襖步出監(jiān)牢的瞬間校辩,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工辆童, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人惠赫。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓把鉴,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親儿咱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子庭砍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容

  • 基本內(nèi)置類型 算術(shù)類型字符整型布爾值浮點(diǎn)數(shù) 空類型(void) 算術(shù)類型 帶符號(hào)類型和無(wú)符號(hào)類型int怠缸、short...
    2625K閱讀 3,127評(píng)論 0 1
  • C++是在C語(yǔ)言的基礎(chǔ)上發(fā)展來(lái)的。C++除了有C語(yǔ)言的指針外钳宪,還增加一個(gè)新的概念——引用揭北,初學(xué)者容易把引用和指針混...
    蕭瀟公舉閱讀 8,511評(píng)論 1 5
  • 1.語(yǔ)言中變量的實(shí)質(zhì) 要理解C指針,我認(rèn)為一定要理解C中“變量”的存儲(chǔ)實(shí)質(zhì)吏颖, 所以我就從“變量”這個(gè)東西開(kāi)始講起吧...
    金巴多閱讀 1,732評(píng)論 0 9
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,506評(píng)論 1 51
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,089評(píng)論 1 32