日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
C++基礎(chǔ)之指針的詳細介紹(二)

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

類烏齊ssl適用于網(wǎng)站、小程序/APP、API接口等需要進行數(shù)據(jù)傳輸應(yīng)用場景,ssl證書未來市場廣闊!成為成都創(chuàng)新互聯(lián)公司的ssl證書銷售渠道,可以享受市場價格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:13518219792(備注:SSL證書合作)期待與您的合作!

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

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

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

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

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

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

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

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

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

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

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

類型修飾符(type-specifier)

類型修飾符,即對類型起修飾作用的符號,在定義變量時用于進一步指明如何操作變量對應(yīng)的內(nèi)存。因為一些通用操作方式,即這種操作方式對每種類型都適用,故將它們單獨分離出來以方便代碼的編寫,就好像水果。吃蘋果的果肉、吃梨的果肉,不吃蘋果的皮、不吃梨的皮。這里蘋果和梨都是水果的種類,相當(dāng)于類型,而“XXX的果肉”、“XXX的皮”就是用于修飾蘋果或梨這種類型用的,以生成一種新的類型——蘋果的果肉、梨的皮,其就相當(dāng)于類型修飾符。

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

類型修飾符只在定義變量時起作用,如前面的

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

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

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

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

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

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

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

對于

 
 
 
  1. pA = &a;

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

對于

 
 
 
  1. ppA = &pA;

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

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

 
 
 
  1. long **&a = ppA;

但不能

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

因為按照從左到右的修飾符計算順序,long*&*表示long的指針的引用的指針,引用只是告知編譯器不要為變量在棧上分配內(nèi)存,實際與類型無關(guān),故引用的指針是無意義的。

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

 
 
 
  1. long &a[40];//錯誤的

因為其表示分配一塊可連續(xù)存放類型為long的引用的40個元素的內(nèi)存,引用只是告知編譯器一些類型無關(guān)信息的一種手段,無法作為類型的一種而被實例化。

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

 
 
 
  1. long **&rppA = &pA;是錯誤的

因為上句表示的是不要給變量rppA分配內(nèi)存,直接使用“=”后面的地址作為其對應(yīng)的地址,而&pA返回的并不是地址類型的數(shù)字,而是指針類型,故編譯器將報類型不匹配的錯誤。

但是即使

 
 
 
  1. long **&rppA = pA;

也同樣失敗,因為long*和long**是不同的,不過由于類型的匹配,下面是可以的:

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

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

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

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

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

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

故C++提出上面的語法,即將變量名用括號括起來,表示里面的類型最后修飾,

故:

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

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

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

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

將報錯(前面已說明原因)。而

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

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

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

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


網(wǎng)站標(biāo)題:C++基礎(chǔ)之指針的詳細介紹(二)
網(wǎng)頁URL:http://www.dlmjj.cn/article/djcpejh.html