1. 程式人生 > >const在c與c++中的不同地位

const在c與c++中的不同地位

我們都知道,const關鍵字是防止某個變數被修改的,即限定這個變數是隻讀的。C/C++中應用const會使程式的健壯性更高一些。

一、const修飾一般變數

在C中,const修飾一般變數是常變數,它具有變數屬性,但同時,它又具有常性不可被修改。

在C++中,加const修飾以後變數就是個常量,不可被修改。

二、const修飾指標變數

先回想一下我們以前在C中寫一段程式碼時傳參的方式有傳值和傳址兩種,但是大家也都知道傳值的方式就是在函式內部做了一份臨時拷貝,但出了這個函式的作用域臨時變數就會被銷燬。而利用指標傳址的方式又不安全,例如下面這段程式碼:

//傳址方式-----不安全
void print2(int *pa)
{
	*pa = 20;   //a的值會發生改變
	cout<<*pa<<endl; //輸出為20
}
int main()
{
	int a = 10;
	print2(&a);
	system("pause");
	return 0;
}

這樣,即便是一個簡單的輸出函式也會變得不安全,因此我們會加const使其變為安全的:

void print2(const int *pa)
//注意這塊的const一定在*左邊而不是在*右邊,*放在右邊修飾的是a,說明這個a是不能被修改的
{
	cout<<*pa<<endl; 
}

在c/c++中,const修飾指標變數時需要考慮const的位置:

這時就應該弄清楚一個概念:指標常量和常量指標

(1)常量指標:中心詞是指標,用常量來修飾指標,其本質是一個指標,說明這個指標是一個指向常量的指標,即指標本身是可以修改的,但指標指向的變數不可修改

(2)指標常量:中心詞是常量,用指標修飾,本質是一個常量,說明這個常量的值應該是一個指標,即指標本身的值是不能改變的,而通過指標指向的變數的值是可以改變的

	int a = 1;
	int b = 3;
	const int *p = &a;//常量指標
	int const *p = &a;//常量指標
	int* const p = &a;//指標常量

C++中的const引用:

1.引用一個常量時,必須用const修飾——常量不可被修改

#include<iostream>
#include<cstdlib>   //在.cpp檔案中使用.h標頭檔案時,前邊加上c並去掉.h
using namespace std;
int main()
{
	const int &refn = 5;
	return 0;
}

2.const修飾一個變數時:(先看一段錯誤程式碼)

int main()
{
	const int n = 10;
	int &refn = n;
	return 0;
}

refn作為n的引用,二者用的是同一個空間,按理來說,這一塊空間只具有一個安全屬性,要麼是安全的要麼是不安全的。但是從上邊程式碼來看,n加了const保護不可被修改,但refn不具有安全屬性,即它所代表的空間內容可被修改,這樣就產生了矛盾。因此,要想refn稱為n的引用,這裡必須加上const保護。即:const int& refn = n;

3.const修飾一個引用時可以對該變數加以保護

int main()
{
	int a = 0;
	const int &refa = a;
	refa = 10;   //欲通過refa來改變a的值,
	system("pause");
	return 0 ;
}
引用加了const保護從而使a的這塊空間不會被改變,增加了其安全屬性。因此我們也可以將引用作為引數(由於不需要拷貝一份臨時變數,效率會高一些):
//引用傳參
void print3(const int &refa)
{
	cout<<refa<<endl;
}
int main()
{
	int a = 10;
	print3(a);
	system("pause");
	return 0;
}

4.const修飾全域性變數,不一定會為其開闢空間。


const修飾全域性變數,不一定會為其開闢空間。如果不對n進行直接的操作,那麼n這塊空間是還沒被開闢的,這時候const的作用和#define一樣,在程式中僅僅只是替換n。只有在需要使用n所屬的空間時系統才會開闢一塊空間出來,因此,上邊程式碼中的&n操作就會出現錯誤。(和底下這段程式碼作比較)


這段程式碼中需要用p指標指向n的這塊空間的地址,編譯器為其開闢了空間

5.引用的型別與已定義的變數型別不同

//這段程式碼是錯誤的

int main()
{
	double d1 = 1.2;
	int &d2 = d1;
	system("pause");
	return 0 ;
}

//這段程式碼在編譯時只產生警告

int main()
{
	double d1 = 1.2;
	const int &refd2 = d1;
	system("pause");
	return 0 ;
}

從上邊兩端程式碼看得出,僅僅只有一個const之差,那麼為什麼會產生這樣的差異呢?!我們接下來分析一下:


通過除錯我們可以發現,d1和d2用的並不是同一塊空間,說明d2根本就不是d1的引用。在這裡其實是有一些變化的,當int型別的d2要作為double型別的d1的引用時,由於兩者型別不同,會根據d1產生一個int型別的臨時變數(匿名變數),而d2是這個臨時變數的引用。臨時變數一般是不能被修改的,因此在這裡加了const。

因此,以後在變數與該變數的引用之間有型別變化時一定要加const修飾