void main() {
const int a = 10;
printf("initial a = %d\n", a);
int *ptr = &a;
*ptr = 100;
printf("modify a = %d\n", a);
}
複製代碼
運行結果:c++
const int a = 10;
//不能用變量初始化全局const變量,編譯器不經過:表達式必須含有常量值
//const int b = a;
void main() {
printf("first a = %d\n", a);
int *ptr = &a;
//編譯器經過,但運行階段發生寫入錯誤
*ptr = 100;
printf("second a = %d\n", a);
}
複製代碼
運行結果:express
因爲分文件編寫,很差呈現,因此在這裏不爲你們提供c語言全局const變量默認爲外部聯編的案例。若是各讀者有興趣,可自行嘗試。具體步驟以下,可新建一個源文件,而且提供a變量的聲明,如:extern const int a。對於基本類型,以符號表中的數據進行初始化的普通局部const變量,此時不會分配內存,將其放入符號表中,若是對它取地址,則會開闢一個新的空間,也就是說會建立一個臨時變量,若是經過地址間接進行修改值不會影響到其自己。測試代碼以下:bash
const int a = 10;
int *ptr = const_cast<int*>(&a);
*ptr = 100;
cout <<"a = "<<a << endl;
cout <<"*ptr = "<<*ptr << endl;
複製代碼
運行結果:函數
在這裏解釋一下上述代碼:第二行代碼,使用了const(expression),顯示轉換,這是因爲c++比c類型轉換更嚴格。因此須要將 const int * 轉換爲 int * 纔可以進行賦值,而且第二行代碼將被隱式轉換爲以下代碼:int temp=a;
int *ptr=&temp;
//因此對指針 ptr 指向的內存空間進行操做,並不會影響到 a。
複製代碼
對於基本類型,用變量初始化的普通局部const變量,此時會在堆棧區開闢內存,能夠經過地址間接修改值。測試代碼以下:測試
int b = 10;
const int a = b;
int *ptr = const_cast<int*>(&a);
*ptr = 100;
cout << "a = " << a << endl;
cout << "b = " << a << endl;
cout << "*ptr = " << *ptr << endl;
複製代碼
運行結果:ui
(3)對於自定義類型,都會分配內存,能夠經過地址間接修改值this
class Person
{
public:
Person(int age) { this->age = age; };
~Person() {};
int age;
private:
};
int main()
{
const Person personA(20);
Person* personPtr = const_cast<Person *>(&personA);
personPtr->age = 100;
cout <<"personPtr->age = "<<personPtr->age << endl;
}
複製代碼
運行結果:spa
二、普通全局const變量3d
三、const 成員變量/成員函數指針
const成員變量只能被const成員函數訪問
const成員函數,可以訪問全部成員變量,可是在函數體內不能直接修改變量的值(包括普通成員變量),若是須要在函數體內修改普通成員變量的值,須要在變量定義的前面添加mutable關鍵字,或者經過地址間接修改。注意:const成員函數只能被該類的const對象訪問。測試代碼以下:
class Person
{
public:
Person() {};
~Person() {};
void test()const
{
//沒有加mutable修飾的變量在const成員函數內不能直接修改
//b = 20;
//能夠經過地址間接修改
int* Bptr = const_cast<int*>(&b);
*Bptr = 1000;
//使用mutable修飾的變量能夠經過
c = 30;
cout << b << endl;
cout << c << endl;
}
private:
const int a=10;
int b = 100;
mutable int c = 20;
};
int main()
{
Person p;
p.test();
return 0;
}
複製代碼
運行結果:
c語言全局const會被存儲到只讀數據段。c++中全局const當聲明extern或者對變量取地址時,編譯器會分配存儲地址,變量存儲在只讀數據段。兩個都受到了只讀數據段的保護,不可修改。
c語言中局部const存儲在堆棧區,只是不能經過變量直接修改const只讀變量的值,可是能夠跳過編譯器的檢查,經過指針間接修改const值。
c++中對於局部的const變量要區別對待:
(1)對於基礎數據類型,也就是const int a = 10這種,編譯器會把它放到符號表中,不分配內存,當對其取地址時,會分配內存。 a在符號表中,當咱們對a取地址,這個時候爲a分配了新的空間,*p操做的是分配的空間,而a是 從符號表得到的值。
(2)對於基礎數據類型,若是用一個變量初始化const變量,若是const int a = b,那麼也是會給a分配內存。
(3)對於自定數據類型,好比類對象,也會分配內存。
c中const默認爲外部鏈接,c++中const默認爲內部鏈接.當c語言兩個文件中都有const int a的時候,編譯器會報重定義的錯誤。而在c++中,則不會,由於c++中的const默認是內部鏈接的。若是想讓c++中的const具備外部鏈接,必須顯示聲明爲: extern const int a = 10;