成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C++基礎之指針的詳細介紹(二)

開發 后端
本篇說明C++中的重中又重的關鍵——指針類型,并說明兩個很有意義的概念——靜態和動態。希望對你有幫助,一起來看。

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

在堆上分配內存

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

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

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

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

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

 

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

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

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

 

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

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

類型修飾符(type-specifier)

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

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

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

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

 

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

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

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

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

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

 

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

對于

  1. pA = &a; 

 

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

對于

  1. ppA = &pA; 

 

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

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

  1. long **&a = ppA; 

 

但不能

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

 

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

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

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

 

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

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

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

 

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

但是即使

  1. long **&rppA = pA; 

 

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

 

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

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

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

 

即動態分配一塊4*45=180字節的連續內存空間,并將首地址返回給ppA.同樣也就可以:

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

 

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

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

故:

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

 

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

 

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

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

 

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

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

 

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

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

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

責任編輯:于鐵 來源: 互聯網
相關推薦

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-06-21 10:37:56

const

2011-07-14 16:26:01

2011-07-20 14:12:48

2011-07-15 10:08:11

C++運算符重載

2011-07-13 11:12:43

C++MFC

2011-07-20 18:03:54

CC++

2010-02-01 10:22:51

C++數據指針

2011-07-13 16:14:53

C++引用指針

2009-08-21 15:16:23

C#使用指針

2011-07-15 01:29:39

C++析構函數

2011-07-15 01:20:58

C指針函數函數指針

2011-07-13 16:49:59

C++

2011-07-20 15:58:53

C++引用

2010-01-28 13:57:19

C++指針基礎

2011-07-20 13:57:06

C++STL
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩精品一区二区三区高清免费 | 欧美亚洲视频 | 日韩三级视频 | www.97国产 | 精品亚洲一区二区 | 成人毛片视频免费 | 黑人精品欧美一区二区蜜桃 | 日韩欧美精品一区 | av在线天堂网 | 中文字幕色站 | av综合站| 日本亚洲一区 | 在线观看视频一区二区三区 | 人和拘一级毛片c | 国产成人精品视频 | 欧美精品区 | 日韩精品一区二区久久 | 国产亚洲精品久久久优势 | 亚洲精品电影 | 五月综合激情网 | 免费观看羞羞视频网站 | 秋霞在线一区 | 在线免费av观看 | 色婷婷国产精品综合在线观看 | 亚洲视频www | 天天干免费视频 | 欧美一区| 亚洲国产精品99久久久久久久久 | 国产真实精品久久二三区 | 黄色三级在线播放 | 99精品视频免费观看 | 久久久久av | 欧美高清一级片 | 久久99精品久久久 | 免费看黄色视屏 | 欧美影院| 欧美精品一区二区三区蜜桃视频 | 黄色在线播放视频 | 精品久久久久久久久亚洲 | 久久精品国产99国产精品 | a级片在线观看 |