自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

C++基礎(chǔ)之指針的詳細(xì)介紹(二)

開(kāi)發(fā) 后端
本篇說(shuō)明C++中的重中又重的關(guān)鍵——指針類(lèi)型,并說(shuō)明兩個(gè)很有意義的概念——靜態(tài)和動(dòng)態(tài)。希望對(duì)你有幫助,一起來(lái)看。

本篇是上一篇的續(xù)篇,接著為大家介紹C++中的指針。

在堆上分配內(nèi)存

前面已經(jīng)說(shuō)過(guò),所謂的在堆上分配就是運(yùn)行時(shí)期向操作系統(tǒng)申請(qǐng)內(nèi)存,而要向操作系統(tǒng)申請(qǐng)內(nèi)存,不同的操作系統(tǒng)提供了不同的接口,具有不同的申請(qǐng)內(nèi)存的方式,而這主要通過(guò)需調(diào)用的函數(shù)原型不同來(lái)表現(xiàn)。由于C++是一門(mén)語(yǔ)言,不應(yīng)該是操作系統(tǒng)相關(guān)的,所以C++提供了一個(gè)統(tǒng)一的申請(qǐng)內(nèi)存的接口,即new操作符。如下:

  1. unsigned long *pA = new unsigned long;   
  2. *pA = 10;  
  3. unsigned long *pB = new unsigned long[ *pA ]; 

上面就申請(qǐng)了兩塊內(nèi)存,pA所指的內(nèi)存(即pA的值所對(duì)應(yīng)的內(nèi)存)是4字節(jié)大小,而pB所指的內(nèi)存是4*10=40字節(jié)大小。應(yīng)該注意,由于new是一個(gè)操作符,其結(jié)構(gòu)為new <類(lèi)型名>[<整型數(shù)字>].它返回指針類(lèi)型的數(shù)字,其中的<類(lèi)型名>指明了什么樣的指針類(lèi)型,而后面方括號(hào)的作用和定義數(shù)組時(shí)一樣,用于指明元素的個(gè)數(shù),但其返回的并不是數(shù)組類(lèi)型,而是指針類(lèi)型。

應(yīng)該注意上面的new操作符是向操作系統(tǒng)申請(qǐng)內(nèi)存,并不是分配內(nèi)存,即其是有可能失敗的。當(dāng)內(nèi)存不足或其他原因時(shí),new有可能返回?cái)?shù)值為0的指針類(lèi)型的數(shù)字以表示內(nèi)存分配失敗。即可如下檢測(cè)內(nèi)存是否分配成功。

  1. unsigned long *pA = new unsigned long[10000];  
  2. if( !pA )? // 內(nèi)存失?。∽鱿鄳?yīng)的工作 

 

上面的if是判斷語(yǔ)句,下篇將介紹。如果pA為0,則!pA的邏輯取反就是非零,故為邏輯真,進(jìn)而執(zhí)行相應(yīng)的工作。

只要分配了內(nèi)存就需要釋放內(nèi)存,這雖然不是必須的,但是作為程序員,它是一個(gè)良好習(xí)慣(資源是有限的)。為了釋放內(nèi)存,使用delete操作符,如下:

  1. delete pA;   
  2. delete[] pB; 

 

注意delete操作符并不返回任何數(shù)字,但是其仍被稱(chēng)作操作符,看起來(lái)它應(yīng)該被叫做語(yǔ)句更加合適,但為了滿(mǎn)足其依舊是操作符的特性,C++提供了一種很特殊的數(shù)字類(lèi)型——void.其表示無(wú),即什么都不是,因此delete其實(shí)是要返回?cái)?shù)字的,只不過(guò)返回的數(shù)字類(lèi)型為void罷了。

注意上面對(duì)pA和pB的釋放不同,因?yàn)閜A按照最開(kāi)始的書(shū)寫(xiě),是new unsigned long返回的,而pB是new unsigned long[ *pA ]返回的。所以需要在釋放pB時(shí)在delete的后面加上“[]”以表示釋放的是數(shù)組,不過(guò)在VC中,不管前者還是后者,都能正確釋放內(nèi)存,無(wú)需“[]”的介入以幫助編譯器來(lái)正確釋放內(nèi)存,因?yàn)橐訵indows為平臺(tái)而開(kāi)發(fā)程序的VC是按照Windows操作系統(tǒng)的方式來(lái)進(jìn)行內(nèi)存分配的,而Windows操作系統(tǒng)在釋放內(nèi)存時(shí),無(wú)需知道欲釋放的內(nèi)存塊的長(zhǎng)度,因?yàn)槠湟呀?jīng)在內(nèi)部記錄下來(lái)(這種說(shuō)法并不準(zhǔn)確,實(shí)際應(yīng)是C運(yùn)行時(shí)期庫(kù)干了這些事,但其又是依賴(lài)于操作系統(tǒng)來(lái)干的,即其實(shí)是有兩層對(duì)內(nèi)存管理的包裝,在此不表)。

類(lèi)型修飾符(type-specifier)

類(lèi)型修飾符,即對(duì)類(lèi)型起修飾作用的符號(hào),在定義變量時(shí)用于進(jìn)一步指明如何操作變量對(duì)應(yīng)的內(nèi)存。因?yàn)橐恍┩ㄓ貌僮鞣绞?,即這種操作方式對(duì)每種類(lèi)型都適用,故將它們單獨(dú)分離出來(lái)以方便代碼的編寫(xiě),就好像水果。吃蘋(píng)果的果肉、吃梨的果肉,不吃蘋(píng)果的皮、不吃梨的皮。這里蘋(píng)果和梨都是水果的種類(lèi),相當(dāng)于類(lèi)型,而“XXX的果肉”、“XXX的皮”就是用于修飾蘋(píng)果或梨這種類(lèi)型用的,以生成一種新的類(lèi)型——蘋(píng)果的果肉、梨的皮,其就相當(dāng)于類(lèi)型修飾符。

本文所介紹的數(shù)組和指針都是類(lèi)型修飾符,之前提過(guò)的引用變量的“&”也是類(lèi)型修飾符。

類(lèi)型修飾符只在定義變量時(shí)起作用,如前面的

  1. unsigned long a, b[10], *pA = &a, &rA = a; 

 

這里就使用了上面的三個(gè)類(lèi)型修飾符——“[]”、“*”和“&”。上面的unsigned long暫且叫作原類(lèi)型,表示未被類(lèi)型修飾符修飾以前的類(lèi)型。下面分別說(shuō)明這三個(gè)類(lèi)型修飾符的作用。

數(shù)組修飾符“[]”——其總是接在變量名的后面,方括號(hào)中間放一整型數(shù)c以指明數(shù)組元素的個(gè)數(shù),以表示當(dāng)前類(lèi)型為原類(lèi)型c個(gè)元素連續(xù)存放,長(zhǎng)度為原類(lèi)型的長(zhǎng)度乘以c.因此long a[10];就表示a的類(lèi)型是10個(gè)long類(lèi)型元素連續(xù)存放,長(zhǎng)度為10*4=40字節(jié)。而long a[10][4];就表示a是4個(gè)long[10]類(lèi)型的元素連續(xù)存放,其長(zhǎng)度為4*40=160字節(jié)。

相信已經(jīng)發(fā)現(xiàn),由于可以接多個(gè)“[]”,因此就有了計(jì)算順序的關(guān)系,為什么不是10個(gè)long[4]類(lèi)型的元素連續(xù)存放而是倒過(guò)來(lái)?類(lèi)型修飾符的修飾順序是從左向右進(jìn)行計(jì)算的。故short *a[10];表示的是10個(gè)類(lèi)型為short*的元素連續(xù)存放,長(zhǎng)度為10*4=40字節(jié)。

指針修飾符“*”——其總是接在變量名的前面,表示當(dāng)前類(lèi)型為原類(lèi)型的指針。故:

  1. short a = 10, *pA = &a, **ppA = &pA; 

 

注意這里的ppA被稱(chēng)作多級(jí)指針,即其類(lèi)型為short的指針的指針,也就是short**.而short **ppA = &pA;的意思就是計(jì)算pA的地址的值,得一類(lèi)型為short*的地址類(lèi)型的數(shù)字,然后“&”操作符將此數(shù)字轉(zhuǎn)成short*的指針類(lèi)型的數(shù)字,最后賦值給變量ppA.
如果上面很昏,不用去細(xì)想,只要注意類(lèi)型匹配就可以了,下面簡(jiǎn)要說(shuō)明一下:假設(shè)a的地址為2000,則pA的地址為2002,ppA的地址為2006.

對(duì)于

  1. pA = &a; 

 

先計(jì)算“&a”的值,因?yàn)閍等同于地址,則“&”發(fā)揮作用,直接將a的地址這個(gè)數(shù)字轉(zhuǎn)成long*類(lèi)型并返回,然后賦值給pA,則pA的值為2000.

對(duì)于

  1. ppA = &pA; 

 

先計(jì)算“&pA”的值,因?yàn)閜A等同于地址,則“&”發(fā)揮作用,直接將pA的地址這個(gè)數(shù)字轉(zhuǎn)成long**類(lèi)型(因?yàn)閜A已經(jīng)是long*的類(lèi)型了)并返回,然后賦值給ppA,則ppA的值為2002.

引用修飾符“&”——其總是接在變量名的前面,表示此變量不用分配內(nèi)存以和其綁定,而在說(shuō)明類(lèi)型時(shí),則不能有它,下面說(shuō)明。由于表示相應(yīng)變量不用分配內(nèi)存以生成映射,故其不像上述兩種類(lèi)型修飾符,可以多次重復(fù)書(shū)寫(xiě),因?yàn)闆](méi)有意義。且其一定在“*”修飾符的右邊,即可以

  1. long **&a = ppA; 

 

但不能

  1. long *&*a;  
  2. 或  
  3. long &**a; 

 

因?yàn)榘凑諒淖蟮接业男揎椃?jì)算順序,long*&*表示long的指針的引用的指針,引用只是告知編譯器不要為變量在棧上分配內(nèi)存,實(shí)際與類(lèi)型無(wú)關(guān),故引用的指針是無(wú)意義的。

而long&**則表示long的引用的指針的指針,同上,依舊無(wú)意義。同樣

  1. long &a[40];//錯(cuò)誤的 

 

因?yàn)槠浔硎痉峙湟粔K可連續(xù)存放類(lèi)型為long的引用的40個(gè)元素的內(nèi)存,引用只是告知編譯器一些類(lèi)型無(wú)關(guān)信息的一種手段,無(wú)法作為類(lèi)型的一種而被實(shí)例化。

應(yīng)該注意引用并不是類(lèi)型(但出于方便,經(jīng)常都將long的引用稱(chēng)作一種類(lèi)型),而

  1. long **&rppA = &pA;是錯(cuò)誤的 

 

因?yàn)樯暇浔硎镜氖遣灰o變量rppA分配內(nèi)存,直接使用“=”后面的地址作為其對(duì)應(yīng)的地址,而&pA返回的并不是地址類(lèi)型的數(shù)字,而是指針類(lèi)型,故編譯器將報(bào)類(lèi)型不匹配的錯(cuò)誤。

但是即使

  1. long **&rppA = pA; 

 

也同樣失敗,因?yàn)閘ong*和long**是不同的,不過(guò)由于類(lèi)型的匹配,下面是可以的:

 

  1. long a = 10, *pA = &a, **ppA = &pA, *&rpA1 = *ppA, *&rpA2 = *( ppA + 1 ); 

類(lèi)型修飾符和原類(lèi)型組合在一起以形成新的類(lèi)型,如long*&、short *[34]等,都是新的類(lèi)型,應(yīng)注意前面new操作符中的<類(lèi)型名>要求寫(xiě)入類(lèi)型名稱(chēng),則也可以寫(xiě)上前面的long*等,即:

  1. long **ppA = new long*[45]; 

 

即動(dòng)態(tài)分配一塊4*45=180字節(jié)的連續(xù)內(nèi)存空間,并將首地址返回給ppA.同樣也就可以:

  1. long ***pppA = new long**[2];  
  2. 而  
  3. long *(*pA)[10] = new long*[20][10]; 

 

也許看起來(lái)很奇怪,其中的pA的類(lèi)型為long *(*)[10],表示是一個(gè)有10個(gè)long*元素的數(shù)組的指針,而分配的內(nèi)存的長(zhǎng)度為(4*10)*20=800字節(jié)。因?yàn)閿?shù)組修飾符“[]”只能放在變量名后面,而類(lèi)型修飾符又總是從左朝右計(jì)算,則想說(shuō)明是一個(gè)10個(gè)long元素的數(shù)組的指針就不行,因?yàn)榉旁谧髠?cè)的“*”總是較右側(cè)的“[]”先進(jìn)行類(lèi)型修飾。

故C++提出上面的語(yǔ)法,即將變量名用括號(hào)括起來(lái),表示里面的類(lèi)型最后修飾,

故:

  1. long *(a)[10];  
  2. 等同于  
  3. long *a[10];  

 

  1. long *(&aa)[10] = a; 

 

也才能夠正確,否則按照前面的規(guī)則,使用

  1. long *&aa[10] = a; 

 

將報(bào)錯(cuò)(前面已說(shuō)明原因)。而

  1. long *(*pA)[10] = &a; 

 

也就能很正常地表示我們需要的類(lèi)型了。因此還可以

  1. long *(*&rpA)[10] = pA;  
  2. 以及  
  3. long *(**ppA)[10] = &pA; 

希望通過(guò)本文的介紹,能夠讓你清楚的明白C++中的指針概念以及用法。

責(zé)任編輯:于鐵 來(lái)源: 互聯(lián)網(wǎng)
相關(guān)推薦

2011-07-14 17:02:09

C++指針

2011-07-14 16:56:21

2011-07-14 23:27:05

C++引用

2011-07-20 16:43:34

C++

2011-07-15 01:38:56

C++this指針

2011-07-14 16:26:01

2011-06-21 10:37:56

const

2011-07-20 14:12:48

2011-07-13 11:12:43

C++MFC

2011-07-15 10:08:11

C++運(yùn)算符重載

2011-07-20 18:03:54

CC++

2011-07-13 16:14:53

C++引用指針

2010-02-01 10:22:51

C++數(shù)據(jù)指針

2009-08-21 15:16:23

C#使用指針

2011-07-15 01:29:39

C++析構(gòu)函數(shù)

2011-07-15 01:20:58

C指針函數(shù)函數(shù)指針

2011-07-20 15:58:53

C++引用

2011-07-13 16:49:59

C++

2010-01-28 13:57:19

C++指針基礎(chǔ)

2011-07-20 13:57:06

C++STL
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)