太久不用C++了,竟然連最基本的東西都記不清楚了。今天干活的時候突然想要用指針常量,但突然就忘了指針常量跟常量指針的區別。花了一點兒時間仔細回想了一下幾年前上課時老師講的,總算又回憶起來了,趕緊記錄下來備忘。
這可能會被當作面試題,不過不是算法,故而不放在面試算法題系列中。
我覺得容易混淆的罪魁禍首在於中文的翻譯問題,如果改叫“常量的指針”和“指針常量”可能會好些。先不管這些,看看英文的叫法:Pointer to Const 和 Const Pointer。
Pointer to Const,顧名思義就是一個指針,指向的數據不能被修改,C++語法是int const* ptr。怎麼記憶呢,非常簡單,記住要從右往左解讀即可。首先這是個變量(ptr);然後發現它是個指針(*);接下來看到它所指向的數據是不可修改的(const);最後這個指針所指向的空間存放的是整數(int)。
Const Pointer,也是個指針,但這個指針的值不能被修改(不能再指向其他地方),C++語法是int* const ptr。同樣從右往左讀,變量(ptr);變量的值不能被修改(const);是個指針(*);這個指針所指向的空間存放的是整數(int)。
可見const修飾的是它右邊緊鄰的元素,如果右邊是指針*,就表明指針指向的是常量,不能被修改;如果右邊是變量,就變明這個變量自身不能被修改。
下面這段C++程序示意了兩種指針的區別,其中被注釋掉的兩行(高亮顯示)是因為會無法編譯。
int a1 = 1;
int b1 = 2;
int c1 = 3;
int* pointer = &a1;
int const* pointerToConst = &b1;
int* const constPointer = &c1;
int a2 = 10;
int b2 = 20;
int c2 = 30;
pointer = &a2;
pointerToConst = &b2;
//constPointer = &c2; // the pointer cannot be moved
*pointer += 100;
//*pointerToConst += 100; // the pointed data cannot be changed
*constPointer += 100;
cout << "*pointer = " << *pointer << "\n"
<< "*pointerToConst = " << *pointerToConst << "\n"
<< "*constPointer = " << *constPointer << endl;
顯然程序的輸出應該是:
*pointer = 110
*pointerToConst = 20
*constPointer = 103
對英文名稱理解清楚了,記不記中文名字也就無所謂了吧。我的記憶方法就是“Pointer to Const”翻譯為“常量的指針”,簡稱“常量指針”;“Const Pointer”翻譯為“指針常量”。
最後簡單總結一下跟const相關的變量的寫法:
int a = 0;
int b = 1;
// An int that cannot be changed.
const int constNumber_1 = a;
int const constNumber_2 = a;
//constNumber_1 = 10;
// A pointer that can be repointed to an int that cannot be changed.
const int* pointerToConst_1 = &a;
int const* pointerToConst_2 = &a;
pointerToConst_1 = &b;
//*pointerToConst_1 = 10;
// A pointer that cannot be moved to an integer that may be changed.
int* const constPointer = &a;
//constPointer = &b;
*constPointer = 10;
// A pointer that cannot be moved to an integer that cannot be changed.
const int* const constPointerToConst_1 = &a;
int const* const constPointerToConst_2 = &a;
//constPointerToConst_1 = &b;
//*constPointerToConst_1 = 10;
// Error, const applied to int twice.
// (warning C4114: same type qualifier used more than once).
const int const* pointerToTwiceConst = &a;
pointerToTwiceConst = &b;
//*pointerToTwiceConst = 10;
// A pointer that may be repointed. It points to a pointer that cannot be moved to
// an int that may be modified.
int* pa = &a;
int* const* pointerToConstPointer = &pa;
int* pb = &b;
pointerToConstPointer = &pb;
//*pointerToConstPointer = pb;
**pointerToConstPointer = 10;