2015年8月3日 星期一

const (上)



C++ 中的 const 關鍵字是一修飾符。當我們把撰寫好的程式交給編譯器進行編譯時,「修飾符」是用來告訴編譯器特定的「要求」,修飾符本身並不產生實際的代碼。以 const 修飾符來說,它用來告訴編譯器,被修飾的東西具有「唯讀」的特性,若在編譯的過程中,編譯器發現程式碼試圖改變這些「唯讀」的東西,編譯器就會產生錯誤提示。

妥善的使用 const 可以讓編譯器協助檢查程式碼的正確性。撰寫程式時,只要對「不應該被改變」的地方都加上 const 修飾,則編譯器就會配合檢查這些地方是否有被更動並回報,讓程式設計師易於糾正錯誤。雖然使用 const 對於最終編譯產生的執行碼並無影響,但儘可能使用 const 可以協助程式設計師減少失誤,提高程式碼的正確率。

A. const 修飾變數

以 const 修飾非指標型態的變數,一般有兩種寫法:
const 變數型態 x;
變數型態 const x;

這兩種寫法的作用是一樣的,意思是 const 右側 x 變數的值是不可改變的。
例如:
const int x;   // x 是const
int const y;   // y 是const

但是對於指標類型的變數,不同的寫法會有不同情況,例如:
1. const int * p;
2. int const * p;
3. int * const p;
4. const int * const p;

針對前三種寫法,可以換個方式加上括弧
1. const (int) *p;
2. (int) const *p;
3. (int*) const p;
根據 const 修飾非指標變數的規則,上述 1 2 的結果是一樣的,const 修飾的 *p 為常量不可改變。
對於 3 則有另一種寫法 const (int*) p; 
意思是指 const 修飾 int* 類型的指摽變數 p 為常量,所以 p 指標不可改變。

而第 4 種情況,則是 1 和 3 的混合體,表示指標本身 p 和指標內容 *p 皆為常量不可改變。

總結:
1. 指標所指向的內容是常量不可改變
const (int) *p;
(int) const *p;

2. 指針本身是常量不可改變
(int*) const p;
const (int*) p;

3. 指針本身與指標所指向的內容都不可變
const int* const p;

B. const 修飾函數參數

以 const 修飾函數參數是它最廣泛的用途之一,表示函數中的程式碼不能修改參數的值。
void func(const int a); //a在函數內不可改變 (在此因使用 call by value 所以並無實際效用)
void func(int * const a); //參數指標本身為常量不可變(亦無實效,因 a 也是 call by value)
void func(const int * arg); //參數指標所指內容為常量不可變(注意不可寫反)

以 const 來修飾 call by reference 的參數時,可以得到 call by reference 的效率並保有 call by value 的安全性,是非常好的搭配:
void function(const Class& arg); // Class 為類別名稱
void function(const TYPE& arg); // TYPE 為變數型態

C. const 修飾函數返回值

const 修飾函數返回值的含義,和 const 修飾普通變數或指標的含義類似。
1. const int function1() 
無實際效用,因為函數返回的本來就是值

2. const int * function2() 
實際使用如 const int *p = function2();
可將 function2() 視為變數,經 const 修飾後,指標所指向的內容不可變

3. int * const function3()
實際使用如 int * const p = function3();
可將 function3() 視為變數,經 const 修飾後,指標本身不可變

沒有留言:

張貼留言