對指標的知識點小結
1、指標的宣告和初始化
宣告指向特定型別的指標的格式:typeName * poiterName;
建立指標後,應將記憶體地址賦給它。
int ducks=12; //建立ducks變數,將值12儲存在在該變數中。
int *birddog=&ducks; //建立指標變數birddog,將ducks的地址儲存在該變數中。
將一個指標初始化為一個地址:
#include <iostream> using namespace std; int main(int argc, char *argv[]) { int a=6; int *b=&a; cout<<"Address of a:"<<&a<<endl; cout<<"Address of b:"<<b<<endl; return 0; }
程式將b(而不是*b)初始化為a的地址。
對指標解除引用,其實就是獲得指標的值(如:*b)。
2、使用指標的注意點
(1) 在C++建立指標時,計算機將分配用來儲存地址的記憶體,但不會分配用來儲存指標所指向的資料的記憶體。故必須賦給建立的指標一個明確的記憶體地址。
如:
int * a; //create an empty pointer
*a=5; //this pointer store in where?just place a value in a unsure land
Be care for ! It's dangerous and easy to make mistakes!!!
(2)同陣列!不要指向一個未被初始化的陣列下標中去,這將導致意想不到的錯誤。
#include <iostream> using namespace std; int main(int argc, char *argv[]) { int * pt=new int [10]; pt[0]=1; pt[1]=2; pt[2]=3; cout<<"pt[1] ="<<pt[1]<<endl; pt=pt+1; cout<<"now pt[0]="<<pt[0]<<endl; cout<<"pt[1]="<<pt[3]<<endl; pt=pt-1; delete [] pt; return 0; }
(3)地址不一定是int型的,故需要對地址進行強制型別轉換。
int *pt;
pt=0xB8000000; //type mismatch .
pt=(int *)0xB000000; //type now match.
(4)
int a[10];
a[1]=1;
*(a+2)=2; //the same to a[2]
(5)在C++中,用引號括起來的字串像陣列名一樣,也是第一個元素的地址。
const char *bird="wren";//bird holds address of string
(6)新建立的空指標,使用賦值法和使用strcpy()賦值的區別
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
char animal[20]="bear";
const char * bird="wren";
char * ps;
cout<<"animal:"<<animal<<"and\n";
cout<<"bird:"<<bird<<"\n";
//cout<<" ps:"<<ps;
cout<<"Enter a kind of animal:";
cin>>animal;
//cin>>ps;
ps=animal;
cout<<"ps:"<<ps<<endl;
cout<<"Before using strcpy():\n";
cout<<animal<<" at "<<(int *)animal<<endl;
cout<<ps<<" at "<<(int *)ps<<"\n";
ps=new char[strlen(animal)+1];
strcpy(ps,animal);
//ps=animal;
cout<<"After using strcpy():\n";
cout<<animal<<" at "<<(int *)animal<<endl;
cout<<ps<<" at "<<(int *)ps<<endl;
//delete [] ps;
return 0;
}
使用賦值語句給指標賦值,實際是將陣列的地址和數值傳遞給了指標,使該指標任然指向該地址。使用strcpy()語句,會重新分配一個獨立的地址,然後將值傳遞給指標,使指標指向該獨立的地址。
3、使用new和delete
(1)為一個數據物件(可以是結構,也可以是基本型別)獲得並指定分配記憶體的通用格式:
typename pointer_name=new typename;
如:int * pt=new int;
long *pd=new long;
(2)建立指標時,會分配記憶體空間來指向儲存的記憶體地址。可以使用delete來釋放指標指向的地址,但不會刪除指標本身。
如:int *pt=new int; //allocate memory with new;
delete pt; //free memory with delete when done;but will not delete itself,you can point it to a new allocate memory
(3)為陣列分配記憶體的通用格式:
type_name pointer_name=new type_name [num_elements];
如:int * psome=new int [3]; //new操作符返回第一個元素的地址,該地址被賦給指標psome,故psome指向陣列的第一個元素的地址,*psome是第一個元素的值。
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int * pt=new int [10];
pt[0]=1;
pt[1]=2;
pt[2]=3;
cout<<"pt[1] ="<<pt[1]<<endl;
pt=pt+1;
cout<<"now pt[0]="<<pt[0]<<endl;
cout<<"pt[1]="<<pt[1]<<endl;
pt=pt-1;
delete [] pt;
return 0;
}
使用delelte的注意事項:
(1)delete只能用於釋放由new分配的記憶體;
(2)對空指標使用delete是安全的;
(3)不要嘗試釋放已經釋放的記憶體,即不要使用delete刪除同一個記憶體塊兩次。
(4)使用new []分配的記憶體,需使用delete []來釋放;
(5)不要建立兩個指向同一個記憶體塊的指標,因為這將增加錯誤地刪除同一個記憶體塊兩次的可能性。
如果new分配的記憶體沒有使用delete進行釋放,則會發生記憶體洩漏(memory leak),也就是被分配的記憶體再也無法使用了。如果記憶體洩漏嚴重,則程式將由於不斷尋找更多記憶體而終止。
指標和物件小結:
- 使用常規表示法來宣告指向物件的指標:String * glamour;
- 可以將指標初始化為指向已有的物件:String * first=&sayings[0];
- 可以使用new來初始化指標,這將建立一個新的物件:
-
//invokes default constructor String * gleep=new String; //invokes the String(const char *) constructor String * glop=new String("my my my"); //invokes the String(const String &) constructor String * favorite=new String(sayings[choice]);
- 可以使用->操作符通過指標訪問類方法:if(sayings[i].length()<shortest->length())
- 可以對物件指標應用解除引用操作符(*)來獲得物件:
if(sayings[i]<*first) first=&sayings[i]; //assign object address