C/C++中的const

一、C中的const

  • 一、局部const變量存放在堆棧區中,會分配內存(也就是說能夠經過地址間接修改變量的值)。測試代碼以下:
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變量存放在只讀數據段(不能經過地址修改,會發生寫入錯誤), 默認爲外部聯編,能夠給其餘源文件使用(須要用extern關鍵字修飾)
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。

二、C++中的const

  • 一、普通局部const變量

對於基本類型,以符號表中的數據進行初始化的普通局部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變量基本相同,只是內存開闢在全局/堆區,對於c++而言,全局const變量默認爲內部聯編,能夠在定義時加extern關鍵字聲明爲外部聯編。 因爲分文件編寫很差展現,請讀者自行嘗試。
  • 三、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/C++中const異同總結

  • 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;

以上內容若有錯誤請聯繫我進行改正,謝謝!!!

相關文章
相關標籤/搜索