C++——指針復習
一、基本概念
1、 內存存儲原理
如果在程序中定義一個變量,在編譯時就給這個變量分配內存單位。系統根據程序中定義的變量類型,分配一定長度的空間。例如,C++編譯系統一般為整形變量分配4個字節,為單精度浮點型變量分配4個字節,為字符型變量分配1個字節。內存區的每一個字節有一個編號,這就是“地址”,它相當於旅館中的房間號。在地址所標識的內存但願中存放數據,這相當於旅館中各個房間中居住旅客一樣。
區別:內存單元的地址與內存單元的內容
假設程序已定義了3哥整型變量,I,j,k,編譯時系統分配2000,2001,2002,2003這4個字節給變量I,分配2004,2005,2006,2007字節給j,分配2008,2009.,2010,2011字節給k。在程序中一般是通過變量名來對內存單位進行存取操作的。程序經過編譯以後已經將變量名轉換為變量的地址,對變量值的存取都是通過地址進行的。例如,語句“cout<<I”;的執行是這樣的:根據變量名與地址的對應關系(這個對應關系是在編譯時確定的),找到變量i的地址2000,然後從由2000開始的4個字節中取出數據(即變量的值3),把它輸出。輸入時如果用”cin>>I;”,在執行時,就把從鍵盤輸入的值送到地址為2000開始的整型存儲但願中。如果有語句:”k=i+j;”,則從2000字節開始的整型變量存儲但願中取出i的值(3),從2004字節開始的變量存儲但願中取出j的值(6),將它們相加後再將其和(9)送到k所占用的2008字節開始的整型存儲單元中。這種按變量地址存取變量值的方式稱為直接存取方式,或直接訪問方式。
還可以采用另一種成為簡介存取(間接訪問)的方式,將變量i的地址存放在另一個變量中。可以在程序中定義這樣一種特殊的變量,它是專門用來存放地址的。假設定義了一個變量i_pointer,用來存放一個整型變量的地址。編譯系統給這個變量分配4個字節(假定為3010-3013字節)。可以通過下面語句將i的起始地址(2000)存放到i_pointer中。
I_pointer=&I;
&是取地址運算符,&i是變量i的地址。執行此語句後,i_pointer的值就是2000(即變量i所占用但願的起始地址)。若要取變量i的值,除了可以用直接方式外,還可以采用間接方式:先找到存放“I”的地址的變量i_pointer,從中取出i的地址(即2000),然後到2000開始的4個字節中取出i的值(3)。
指針定義:一個變量的地址稱為該變量的指針。
指針變量:一個變量專門用來存放另一個變量地址(即指針)的,則它稱為指針變量。
區別:指針與指針變量
指針變量的值(即指針變量中存放的值)是地址(即指針)。例如:變量i的指針是2000,而不能說i的指針變量是2000.
變量與指針
變量的指針就是變量的地址。用來存放變量地址的變量是指針變量。指針變量是一種特殊的變量,它和以前學過的其它類型的變量不同之處:用它來指向另一個變量。為了表示指針變量和它所指向的變量之間的聯系,在C++中用”*”符號表示指向,例如,i_pointer是一個指針變量,而*i_pointer表示i_pointer所指向的變量。*i_pointer也代表一個變量,它就是i_pointer所指向的變量i。
如下兩個語句作用相同:
i=3;
*i_pointer=3;
第二個語句的含義是將3賦給指針變量i_pointer所指向的變量i。
定義一個指針變量:
C++規定所有變量在使用前必須先定義,即指定其類型。在編譯時按變量類型分配存儲空間。對指針變量必須將它定義為指針類型。
int i,j; //定義整型變量i,j
int *pointer_1,*pointer_2; //定義指針變量*pointer_1,*pointer_2
第二行開頭的int是指:所定義的指針變量是指向整型數據的指針變量,或者說,*pointer_1,*pointer_2中只能存放整型數據(如整形變量或整型數組元素)的地址,而不能存放浮點型或其他類型數據的地址。這個int就是指針變量的基類型。指針變量的基類型用來指定該指針變量可以指向的變量類型。
定義指針變量的一般形式:
基類型 *指針變量名;
將一個指針變量指向另一個變量:
pointer_1=&i; //將變量i的地址存放到指針變量pointer_1中
pointer_2=&j; //將變量j的地址存放到指針變量Pointer_2中
這樣,pointer_1就指向了變量i,pointer_2就指向了變量j。
一般的C++編譯系統為每一個指針變量分配4個字節的存儲但願,用來存放變量的地址。
在定義指針變量時要注意:
1、 不能用一個整數給一個指針變量賦初值。例如: int *pointer_1=2000; 是錯誤的,寫此語句者的願意可能是將地址2000作為指針變量pointer_1的初值,但編譯系統並不把2000認為是地址(字節編號),而認為是整數,因此認為是語法錯誤,顯示出錯信息,可以將一個已定義的變量的地址作為指針變量的初值。
int i; //定義整型變量
int *pointer_1=&i; //將變量i的地址作為指針變量pointer_1的初值
2、 在定義指針變量時必須指定基類型。原因:不同類型數據在計算機系統中的存儲方式和所占的字節數不同。
對指針變量的定義“int pointer_1,pointer_2;”,也可以這樣理解:
pointer_1和pointer_2是整型變量,如同int a,b;定義了a和b是整型變量一樣。而*pointer_1和*pointer_2是pointer_1和pointer_2所指向的變量,顯然pointer_1和pointer_2是指針變量。注意:只有整型變量的地址才能被放到基類為整型的指針變量中。
通常為了方便,一般都這樣簡單地敘述:pointer_1,pointer_2是指針變量。其實,完整地說應該是:pinter_1和pointer_2是指向整型數據的指針變量。
引用指針類型
運算符號:&取地址運算符
*指針運算符(或稱簡介訪問運算符)
例如:&a是變量a的地址,*p是指針變量p所指向的存儲單元。
實例:通過指針變量訪問整型變量。
/*
*pointer_1.cpp
*
* Created on: 2012-4-4
* Author: David
*/
#include<iostream>
usingnamespace std;
int main()
{
int a,b; //定義整型變量a,b
int *pinter_1,*pointer_2; //定義指針變量*pinter_1,*pointer_2
a=100;b=10; //對 a,b賦值 www.2cto.com
pointer_1=&a; //把變量a的地址賦給pointer_1
pointer_2=&b; //把變量b的地址賦給pointer_2
cout<<a<<""<<b<<endl; //輸出a和b的值
cout<<*pinter_1<<""<<*pointer_2<<endl; //輸出*pointer_1和*pointer_2的值
return 0;
}
對程序的說明:
1、 在程序中雖然定義了兩個指針變量pointer_1和pointer_2,但它們並非指向任何一個整型變量,而只是提供兩個基類型為整型的指針變量。它們可以指向整型變量,至於指向哪個整型變量,要在程序語句中指定。
2、 pointer_1和pointer_2就是變量a和b,最後兩個cout語句的作用是相同的。
3、 pointer_1=&a和pointer_2=&b是將a和b的地址分別賦給pointer_1和pointer_2。注意不應寫成:*pointer_1=&a;和*pointer_2=&b;因為a的地址是賦給指針變量pointer_1而不是賦給*pointer_1(變量a)。
關於對”*”和”&”運算符的說明:
如果已執行了”pointer_1=&a;”語句,那&*pointer_1的含義是什麼?”&”和”*”兩個運算符的優先級別相同,但按自右向左方向結合,因此先進行*pointer_1的運算,它就是變量a再執行&運算。因此&*pointer_1與&a相同,即變量a的地址。
如果有pointer_2=&*pointer_1;
它的作用是將&a(a的地址)賦給pointer_2,如果pointer_2原來指向b,經過重新賦值後它不再指向b,但也不指向a了。
&a是什麼意思?先進行&a的運算,得a的地址,再進行*運算,即&a所指向的變量,*&a和*pointer_1的作用是一樣的,它們等價於變量a。即*&a與a等價。
實例:大小排序問題
輸入a,b兩個整數,按先大後小的順序輸出a和b(用指針變量處理)
解題思路:設兩個指針變量p1和p2,使它們分別指向a和b,使p1指向a和b中的大者,p2指向小者,順序輸出*p1,*p2就實現了先大後小的順序輸出a和b。按此思路編寫程序如下:
/*
*pointer_2.cpp
*
* Created on: 2012-4-4
* Author: David
*/
#include<iostream>
usingnamespace std;
int main()
{
int *p1,*p2,*p,a,b;
cin>>a>>b;
p1=&a;
p2=&b;
if(a<b)
{
p=p1;
p1=p2;
p2=p;
}
cout<<"a="<<a<<"b="<<b<<endl;
cout<<"max="<<*p1<<"min="<<*p2<<endl;
return 0;
}