1. 程式人生 > >C++深度解析 進化後的const分析(2)

C++深度解析 進化後的const分析(2)

C++深度解析 進化後的const分析(2)

 

 

1 C語言中的const變數

C語言中的const變數是只讀變數,其本質還是變數,會分配儲存空間。(通過列舉enum定義真正的常量

由於const區域性變數會存放在裡,而const全域性變數會存在只讀儲存記憶體上。

所以我們可以通過指標來修改const區域性變數,但是修改const全域性變數,會使程式崩潰

示例1:

通過指標來修改const區域性變數

#include <stdio.h>

int main()
{
	const int c = 0;	//const區域性變數
	
	int* p = (int *)&c;	//通過指標修改const變數
	*p = 5;

	printf("c = %d\n", c);
	return 0;
}

輸出結果:

示例2:

#include <stdio.h>

const int c = 0;	//const全域性變數

int main()
{	
	int* p = (int *)&c;	//通過指標修改const變數
	*p = 5;
	printf("c = %d\n", c);
	return 0;
}

輸出結果:

由於指標修改只讀儲存區的資料,所以導致程式崩潰。

 

 

2 C++中的const常量

在C++中,const變數則是真正的常量了,定義時會將其放入符號表中。

所以編譯途中遇到使用const變數時,則直接從符號表中取出常量

只要當該const變數為全域性(使用extern宣告過),或者被使用&操作符時,才會被分配儲存空間。

示例程式碼:

 

#include <stdio.h>

int main()
{
	const int c = 0;	//const區域性變數
	
	int* p = (int *)&c; //使用&操作符,會分配空間
	*p = 5;

	printf("c = %d, p=%d\n", c, *p);
	return 0;
}

結果如下:

為什麼輸出結果會有兩個不同的值?

這是因為使用&c時,會從符號表中取出c的值,並將0存在一個新的分配空間地址

裡,所以*p修改的只是分配出來的空間地址內容,而c還是常量。

 

 

3 符號表

就是編譯器在編譯過程過程中產生的一張表。(符號表是編譯器的內部結構)

所以為c分配的4位元組的空間,毫無意義。只是為了相容c語言。

//將常量c(識別符號)存入符號表
const int c = 0;

//為識別符號c分配4個位元組空間,並不使用
int* p = (int *)&c;

printf("Begin...\n");

//修改的是編譯器為識別符號c分配的空間
*p = 5;

//編譯器會檢視符號表,發現裡面c,值是c
printf("c = %d\n", c);

printf("End...\n");

 

 

4 C++的const 和 巨集定義

4.1 C++中的的const常量類似於巨集定義

const int c = 5; ≈ define c 5

4.2 C++中的const常量在與巨集定義不同

const常量是由編譯器處理,編譯器對const常量進行型別檢查作用域檢查。

define巨集定義前處理器處理,單純的文字替換,不會進行各種檢查

(前處理器是執行編譯器之前執行的程式,用來刪減註釋,巨集變數轉換等)

示例程式碼:

#include <stdio.h>

void f()
{
	//巨集是被前處理器處理的,直接進行文字替換
	#define a 3     //定義巨集
	const int b = 4;//定義區域性變數
}

void g()
{
	printf("a = %d\n", a);	//a=3
	//printf("b = %d\n", b);	//b的作用域f(),在f之外是不能訪問b
}

int main()
{
	const int A = 1;
	const int B = 2;
	//從符號表中取出數值
	int array [A + B] = {0};
	int i = 0;

	for(i = 0; i < (A+B); i++)
	{
		printf("array[%d] = %d\n", i, array[i]);
	}

	f();
	g();

	return 0;
}

因為執行前處理器時,會將預見到的所有a變為3,所以編譯器看到的是printf("a = %d", 3);

而取消//printf("b = %d\n", b);遮蔽後,程式則會報錯,是因為b的作用域只在f()函式裡有效

 

 

5 小結:

C++中的const是一個真正意義上的常量

C++編譯器可能會為constchan常量分配空間

C++完全相容Cyu'y語言中const常量的語法特性