在C++學習使用過程當中,每一個人都不可避免地使用指針,並且都或多或少的接觸過常量指針或指針常量,可是對這兩個的概念仍是很容易搞糊塗的。函數
本文便是簡單描述指針常量和常量指針的區別。學習
常量指針spa
定義:指針
又叫常指針,能夠理解爲常量的指針,也即這個是指針,但指向的是個常量,這個常量是指針的值(地址),而不是地址指向的值。code
關鍵點:對象
1.常量指針指向的對象不能經過這個指針來修改,但是仍然能夠經過原來的聲明修改;
2.常量指針能夠被賦值爲變量的地址,之因此叫常量指針,是限制了經過這個指針修改變量的值;
3.指針還能夠指向別處,由於指針自己只是個變量,能夠指向任意地址;blog
代碼形式:內存
int const* p; const int* p;class
指針常量
變量
定義:
本質是一個常量,而用指針修飾它。指針常量的值是指針,這個值由於是常量,因此不能被賦值。
關鍵點:
1.它是個常量!
2.指針所保存的地址能夠改變,然而指針所指向的值卻不能夠改變;
3.指針自己是常量,指向的地址不能夠變化,可是指向的地址所對應的內容能夠變化;
代碼形式:
int* const p;
指向常量的常指針
定義:
指向常量的指針常量就是一個常量,且它指向的對象也是一個常量。
關鍵點:
1.一個指針常量,指向的是一個指針對象;
2.它指向的指針對象且是一個常量,即它指向的對象不能變化;
代碼形式:
const int* const p;
那如何區分這幾類呢? 帶兩個const的確定是指向常量的常指針,很容易理解,主要是如何區分常量指針和指針常量:
一種方式是看 * 和 const 的排列順序,好比
int const* p; //const * 即常量指針
const int* p; //const * 即常量指針
int* const p; //* const 即指針常量
還一種方式是看const離誰近,即從右往左看,好比
int const* p; //const修飾的是*p,即*p的內容不可經過p改變,但p不是const,p能夠修改,*p不可修改;
const int* p; //同上
int* const p; //const修飾的是p,p是指針,p指向的地址不能修改,p不能修改,但*p能夠修改;
看代碼:
1 //-------常量指針------- 2 const int *p1 = &a; 3 a = 300; //OK,仍然能夠經過原來的聲明修改值, 4 //*p1 = 56; //Error,*p1是const int的,不可修改,即常量指針不可修改其指向地址 5 p1 = &b; //OK,指針還能夠指向別處,由於指針只是個變量,能夠隨意指向; 6 7 //-------指針常量-------// 8 int* const p2 = &a; 9 a = 500; //OK,仍然能夠經過原來的聲明修改值, 10 *p2 = 400; //OK,指針是常量,指向的地址不能夠變化,可是指向的地址所對應的內容能夠變化 11 //p2 = &b; //Error,由於p2是const 指針,所以不能改變p2指向的內容 12 13 //-------指向常量的常量指針-------// 14 const int* const p3 = &a; 15 //*p3 = 1; //Error 16 //p3 = &b; //Error 17 a = 5000; //OK,仍然能夠經過原來的聲明修改值
在實際應用中,常量指針要比指針常量用的多,好比常量指針常常用在函數傳參中,以免函數內部修改內容。
size_t strlen(const char* src); //常量指針,src的值不可改變;
char a[] = "hello";
char b[] = "world";
size_t a1 = strlen(a);
size_t b1 = strlen(b);
雖然a、b是能夠修改的,可是能夠保證在strlen函數內部不會修改a、b的內容。
既然講到了指針,那順便說一下空指針、野指針的問題。
空指針就是保存地址爲空的指針,使用指針時必須先判斷是否空指針,不少問題都是這一步致使的。
野指針是在delete掉指針以後,沒有置0,致使指針隨意指向了一個內存地址,若是繼續使用,會形成不可預知的內存錯誤。
另外指針的誤用很容易形成BUG或者內存泄漏。
看代碼:
1 //-------空指針-------// 2 int *p4 = NULL; 3 //printf("%d",*p4); //運行Error,使用指針時必須先判斷是否空指針 4 5 //-------野指針(懸浮、迷途指針)-------// 6 int *p5 = new int(5); 7 delete p5; 8 p5 = NULL; //必定要有這一步 9 printf("%d",*p5); //隱藏bug,delete掉指針後必定要置0,否則指針指向位置不可控,運行中可致使系統掛掉 10 11 //-------指針的內存泄漏-------// 12 int *p6 = new int(6); 13 p6 = new int(7); //p6本來指向的那塊內存還沒有釋放,結果p6又指向了別處,原來new的內存沒法訪問,也沒法delete了,形成memory leak