常量指針,表述為“是常量的指針”,就是指向常量的指針,關鍵字 const 出現在 * 左邊,表示指針所指向的位址的内容是不可修改的,但指針自身可變。
指針常量,表述為 "是指針的常量", 指針吱聲是一個常量,關鍵字 const 出現在 * 右邊,表示指針自身不可變,但其所指向的位址的内容是可以被修改的。
例:
常量指針:const char* ptr = "hello"
指針常量:char* const ptr = "hello"
這裡看關鍵字靠着誰近,const靠着ptr近說明就是指針常量,就是指針自身不能改變,但所指向的資料可以變;const靠着類型近,說明指針所指向的内容不可變,但指針可以變。
常量指針有兩種寫法:const既可以寫在類型前,又可以寫在類型後。如上面的例子,常量指針: char const* ptr = "hello" 也是正确的。
最後在舉個例子,與疊代器經常在一起用。若希望疊代器所指向的東西不可變,則需要的是 const_iterator。例:
std::vector::const_iterator iter = vec.begin();
*iter = 10; //錯誤,iter是常量指針
iter++;//正确,iter本身可變
若希望疊代器本身不可變,指向的内容可變,則可以這樣寫:
const std::vector::iterator iter = vec.beign();
*iter = 10;//正确,指針常量
iter++; //錯誤,指針本身不可變
指針常量定義時必須初始化,否則報編譯錯誤,因為此時不指派便沒有機會指派了。
下面看幾個簡單的例子,可以說明他們的差別:
第一個
#include
using namespace std;
int main()
{
char *str1 = {"hello"};
char *str2 = {"hello world"};
char * const ptr1 = str1;
//指針常量--指針本身是常量,指向的位址
//不可以變化,但是指向的位址所對應的内容
//可以變化
ptr1 = str2; //錯誤,因為這是一個指針常量
//改變指向的位址了
cout <
return 0;
}
//編譯錯誤 error: assignment of read-only variable 'ptr1'
第二個
#include
using namespace std;
int main()
{
char *str1 = {"hello"};
char *str2 = {"hello world"};
char * const ptr1 = str1;
//指針常量--指針本身是常量,指向的位址
//不可以變化,但是指向的位址所對應的内容
//可以變化
ptr1 = "A";
//錯誤,顯示記憶體錯誤,因為"hello"為常量
//不得修改,意指指針常量中,指針不得改
//常量也不得改
cout <
return 0;
}
第三個
#include
using namespace std;
int main()
{
char *str1 = {"hello"};
char *str2 = {"hello world"};
const char *ptr1 = str1;
//常量指針--指向字元串常量,所指向的字元串
//内容不能變,但是指向的位址可以變化
//相當于在此處将前邊的str1追加定義為常量
ptr1 = str2;//正确 因為指向的位址是可以變化的
cout <
return 0;
}
//輸出 hello world
#include
using namespace std;
int main()
{
char *str1 = {"hello"};
char *str2 = {"hello world"};
const char *ptr1 = str2;
//常量指針--指向字元串常量,所指向的字元串
//内容不能變,但是指向的位址可以變化
//相當于在此處将前邊的str1追加定義為常量
ptr1 = 'A';//錯誤,因為指向的位址的内容是不可以變化的
cout <
return 0;
}
相信從上面四個簡單的例子可以看出他們不一樣的地方吧,在這裡要請大家注意一下的地方是:
指針常量的申明:const 放在*和指針名之間 Type* const pointer;
常量指針的申明:const放在類型說明符之前 const Type* pointer;
實際分兩部分: type* 為指針 const 為常量 自由組合便成為指針常量,常量指針
常量指針、指針常量,我的判斷原則是 const 和 * 的先後順序。const在前常量指針,常量内容不可變,指針可變
*号在前,指針常量,指針不可變,内容可變
const 還可以修飾函數:
如果給以“指針傳遞”方式的函數傳回值加 const修飾,那麼函數傳回值(即指針)的内容不能被修改,該傳回值隻能被賦給加const修飾的同類型指針。例如函數
const char * GetString(void);
如下語句将出現編譯錯誤:
char *str = GetString();
正确的用法是
const char *str = GetString();
如果函數傳回值采用 “值傳遞方式”,由于函數會把傳回值複制到外部臨時的存儲單元中,加const修飾沒有任何價值。