const與指標
以下二種十分容易混淆,而且十分難記。
Pointer to Const (const*)
const右邊是星號*
const保護的是指標位址中的內容
,被const保護的地方代表只能讀取,不能修改。
下圖中,const保護的是0x1000記憶體位址的內容不被修改。
無法使用*取值運算子修改指標的內容。
*指標 = 修改的內容
1
2
3
4
5
6
7
8
9
10
11
12
int main() {
int var1 = 10;
//將var1的位址給指標變數p
int const * p = &var1;
//p指標位址中的內容是常數,常數不能修改,所以不能使用*指標 = 修改的內容
//* p = 11;
//印出var1的值與p指標位址中的值
cout << "var1=" << var1 << ",p=" << * p << endl;
return 0;
}
執行結果
var1=10,p=10
int const * p
可以更改成const int* p
,二者為一樣的意思,只要記得const右邊若先出現星號*而不是變數名,代表指標位址中的內容是唯讀,無法修改。
1
2
3
4
5
6
int main() {
int var1 = 10;
const int* p = &var1;
cout << "var1=" << var1 << ",p=" << * p << endl;
return 0;
}
第3行,int const * p
可以更改成const int* p
。
可以修改指標指向的記憶體位址
1
2
3
4
5
6
7
8
9
10
11
int main() {
int var1 = 10;
int var2 = 20;
//將var1的位址給指標p
const int* p = &var1;
cout << "var1=" << var1 << ",p=" << * p << endl;
//將var2的位址給指標p
p = &var2;
cout << "var2=" << var2 << ",p=" << * p << endl;
return 0;
}
執行結果
var1=10,p=10
var2=20,p=20
const字串指標
Prerequisites:
char *c = "字串內容"
「c指標」指向RODATA區塊的字串「常數」,RODATA是唯讀區塊,無法修改字串常數的內容,但可以修改指標指向到新的字串常數。。
字串指標加上const
因為指向的RODATA已經是字串「常數」,建議在char* 前加上const常數宣告,編譯器才不會出現警告,字串指標加上const代表無法修改RODATA的字元,但可以指向其它常數字串。
下面程式碼,加上const無法修改"abc"常數字串,指標名c,可以指向其它新的常數字串。
1
2
3
4
5
int main() {
const char* c = "abc";
printf("%s \n",c);
return 0;
}
RODATA區塊的字串常數無法修改。
以下會編譯錯誤。
1
2
3
4
5
6
int main() {
const char* c = "abc";
c[1] = g;
printf("%s \n",c);
return 0;
}
指標可以指向其它字串。
1
2
3
4
5
6
int main() {
const char* c = "abc";
c = "zzzz";
printf("%s \n",c);
return 0;
}
zzz
Const Pointer (const 指標變數)
const右邊是指標變數
指標類型* const 指標變數 = 記憶體位址
1
int* const p = &i;
下圖中,const保護的是指標存的記憶體位址不被修改。
p變數的記憶體位址0x1008,儲存的0x1000的記憶體位址,要保護的是儲存的0x1000,不被修改成其它記憶體位址。
使用const修飾指標變數,代表指標不能再指向其它記憶體位址。
使用const修飾指標變數,要初始化記憶體位址,以下編譯失敗,沒有指派記憶體位址給p。
1
2
3
4
5
int main() {
int i = 10;
int* const p;
return 0;
}
不能再更改指標指向的記憶體位址。
1
2
3
4
5
6
7
8
9
10
11
int main() {
int var1 = 10;
int var2 = 11;
//const右邊是指標名p,初始化要指派記憶體位址,不能是nullptr
int* const p = &var1;
//將var2的位址給指標p,會編譯失敗,不能被修改位址。
//p = &var2;
cout << "var1=" << var1 << ",p=" << *p << endl;
return 0;
}
可以修改內容
不能修改指標的記憶體位址,但可以修改記憶體位址的內容。
可使用*取值運算子修改記憶體位址的內容。
*指標 = 修改的內容
1
2
3
4
5
6
7
8
int main() {
int var1 = 10;
int* const p = &var1;
// 可以修改位址中的內容
* p = 55;
cout << "var1=" << var1 << ",p=" << * p << endl;
return 0;
}
執行結果
var1=55,p=55