c primer plus復合型別之指標

2021-07-30 14:09:58 字數 3325 閱讀 8946

指標是乙個變數,其儲存的是值的位址,而不是值本身。

了解:在討論指標之前,我們先看一看如何找到常規變數的位址,只需對變數應用位址運算子&,就可以獲得他的位置,例如

int cups=6;

double donuts=4.5;

cout<<"cups value="《程式輸出:

cups value=6

and cups adress=0x0065fd40

donuts value=4.5

and donuts adress=0x0065fd44

1:指標概念

使用常規變數時,值是指定的量,而位址為派生量。對於指標策略來說,將位址視為指定的量,而值視為派生量。因此,指標名表示的是位址,*運算子被稱為間接值或解除引用運算子,將其用於指標,可以得到該位址處的值。例如,假設manly是乙個指標,則manly表示的是乙個位址,而*manly表示儲存在該位址處的值。*manly和 常規int變數等效。

2:指標的宣告和初始化指標

宣告指標的句法:typename* pointer_name;

例如,int* p_update;宣告了乙個int* 型別的指標,int*是一種復合型別,是指向int的指標。還可以宣告例如,char* str;

宣告了乙個char* 型別的指標。注意:在這裡,p_update和str指向了兩種長度不同的資料型別,但這兩個指標變數本身的長度通常是相同的,也就是說,char的位址和int的位址的長度相同,一般來說,位址需要2個或是4個位元組,這取決於計算機系統。

初始化指標

:初始化的是指標而不是它指向的值。例如,int cups=6;   int* pt=∪︀這裡將pt(而不是*pt)的值設定為&cups

下面程式演示了指標的宣告和初始化

#include using namespace std;

int main()

{ int higgen=5;

int* pt=&higgen;

cout<<"value of higgen="of pt=00f3fd40;

從中可以知道,程式將pt(而不是*pt)初始化higgen的位址。

3:指標的危險

long* fellow;

*fellow=10000;

上述**確實定義了乙個fellow指標,但是它沒有確定的指向,因為沒有將位址賦給fellow。那麼10000將被放置在**存在不確定性,這種不確定性,可能會導致一些難以追蹤的bug。

警告:一定要在對指標應用解除引用運算子(*)之前,將指標初始化為乙個確定的、適當的位址。

4:指標和數字

指標不是整型,雖然計算機通常把位址當做整型來處理。他們兩者是截然不同的概念,整型可以執行加減乘除等運算的數字,而指標描述的是位置,將兩個位址相乘沒有意義,因此,不能簡單地將乙個整數值賦給指標,例如,下面的語句是不合法的:

int* pt;

pt=0xb8000000;

要將數字值作為位址使用,必須進行強制型別轉換,例如

int* pt;

pt=(int*)0xb8000000;

5:使用new來分配記憶體

對指標有一定了解之後,了解一下它是如何實現在程式執行時分配記憶體的。前面描述的指標宣告方法,只是為可以通過名稱直接訪問記憶體提供了乙個別名。指標的真正用武之地在於,在執行階段分配未命名的記憶體以儲存值。在這種情況下,可以通過指標訪問記憶體。在c++中,使用new運算子來分配記憶體。

舉個栗子:int* pn =new int ;在這裡,執行階段為乙個int值分配未命名的記憶體,並使用指標來訪問這個值。這裡的關鍵所在是c++的new運算子,程式設計師要告訴new,需要為哪種資料型別分配記憶體:new將找到乙個長度正確的記憶體塊,並返回該記憶體塊的位址。程式設計師的責任是將該位址賦給乙個指標。就這個例子來說,new int告訴程式,需要適合儲存int的記憶體。new運算子將根據型別來確定需要多少位元組的記憶體。然後,它找到這樣的記憶體,並返回其位址,接下來,將位址賦給pn,pn被宣告為指向int的指標。現在,pn是位址,*pn是儲存在pn裡的值。

為乙個結構或基本型別獲得並指定分配記憶體的通用格式:typename* pointer_name = new typename;

對於指標,需要指出的另一點是,new分配的記憶體塊通常與常規變數宣告分配的記憶體塊不同。new從被稱為堆或自由記憶體區的記憶體區域分配記憶體,而普通變數值儲存在成為棧的記憶體區域內。

6:使用delete釋放記憶體

當需要記憶體時,可以使用new來請求,另一方面是delete運算子,它使得在使用完記憶體塊時,能夠將其還給記憶體池,這是最有效使用記憶體的關鍵。歸還或釋放的記憶體可供程式的其他部分使用。使用delete時,後面要加上指向記憶體塊的指標(這些記憶體塊最初是由new分配的)。

int* ps = new int ;

...delete ps;

這將釋放ps指向的記憶體,而不會刪除ps指標本身,還可以在後續程式中,將ps重新指向新的記憶體區。

一定要配對使用new和delete。

另外,不能使用delete來釋放宣告變數所獲得的記憶體區。

例如,下面寫法是不合法的:

int juge = 10 ;

int* ps=&juge;

delete ps;

警告:只能使用delete來釋放使用new分配的記憶體。

7:使用new來建立動態陣列

方法,只需要將陣列的元素型別和元素數目告訴new即可。必須在型別名後加上方括號,其中包含元素個數。例如,

int* ps = new int[10];
new運算子返回陣列的首位址,賦給指標ps。當程式使用完new分配的記憶體後,應使用delete釋放記憶體區,但是需要使用另一種形式的delete來釋放。例如,

delete  ps ;
方括號告訴程式,應釋放整個陣列。

注意,使用new時,不帶方括號,則delete釋放時也不帶方括號,使用new時,帶方括號,則delete釋放時也帶上方括號。

8:使用動態陣列

要如何訪問動態陣列中的元素呢?只要把指標當做陣列名使用即可,即對於第乙個元素,可以使用ps[0],對於第二個元素,可以使用ps[1],以此類推。例如,

#include using namespace std;

int main()

{ int* pt=new int [3];//建立動態陣列

pt[0]=0;

pt[1]=1;

pt[2]=2;

cout<<"pt[0]="<

ps[0]=0;

now,ps[0]=1;

ps[1]=2;

《C Primer Plus》 復合型別

typename arrayname arraysize 要求arraysize在編譯是已知,不能是變數。陣列作為由基本型別組成的復合資料型別,arrayname要強調是對應基本資料型別組成的陣列 特定陣列 通過下標或索引單獨訪問各個元素 可能引發陣列越界的問題,int a 20 容易錯誤訪問a 2...

c primer plus 復合型別之陣列

編譯器會把陣列名轉換為乙個指標常量,是陣列中的第乙個元素的位址,型別就是陣列元素的位址型別,如 int a 10 陣列名a若出現在表示式中,如int p a 那麼它就轉換為第乙個元素的位址,等價於int p a 0 只有兩種情況下例外 第一種是對陣列名使用sizeof運算子 sizeof a 這將會...

C primer plus 第4章 復合型別

1.陣列初始化 2.字串 兩種方式 c 風格字串 以 0結尾 string類庫 單引號表示字元常量 a 是字串編碼的簡寫,char a a 是正確的。但是 a 表示的是兩個字元a和 0組成的字串,實際上 a 表示的是字串所在的記憶體位址,因此char a a 是非法的 1 cin.getline a...