const幾點用法
2005年 01月08日
面向對象是C++的重要特性.
但是c++在c的基礎上新增加的幾點優化也是很耀眼的
就const直接可以取代c中的#define
以下幾點很重要,學不好後果也也很嚴重
const
1. 限定符聲明變量只能被讀
const int i=5;
int j=0;
...
i=j; //非法,導致編譯錯誤
j=i; //合法
2. 必須初始化
const int i=5; //合法
const int j; //非法,導致編譯錯誤
3. 在另一連接文件中引用const常量
extern const int i; //合法
extern const int j=10; //非法,常量不可以被再次賦值
4. 便於進行類型檢查
用const方法可以使編譯器對處理內容有更多了解。
#define I=10
const long &i=10; /*dapingguo提醒:由於編譯器的優化,使
得在const long i=10; 時i不被分配內存,而是已10直接代入
以後的引用中,以致在以後的代碼中沒有錯誤,為達到說教效
果,特別地用&i明確地給出了i的內存分配。不過一旦你關閉所
有優化措施,即使const long i=10;也會引起後面的編譯錯誤。*/
char h=I; //沒有錯
char h=i; //編譯警告,可能由於數的截短帶來錯誤賦值。
5. 可以避免不必要的內存分配
#define STRING "abcdefghijklmn
"
const char string[]="abcdefghijklm
";
...
printf(STRING); //為STRING分配了第一次內存
printf(string); //為string一次分配了內存,以後不再分配
...
printf(STRING); //為STRING分配了第二次內存
printf(string);
...
由於const定義常量從匯編的角度來看,只是給出了對應的內存地址,
而不是象#define一樣給出的是立即數,所以,const定義的常量在
程序運行過程中只有一份拷貝,而#define定義的常量在內存中有
若干個拷貝。
6. 可以通過函數對常量進行初始化
int value();
const int i=value();
dapingguo說:假定對ROM編寫程序時,由於目標代碼的不可改寫,
本語句將會無效,不過可以變通一下:
const int &i=value();
只要令i的地址處於ROM之外,即可實現:i通過函數初始化,而其
值有不會被修改。
7. 是不是const的常量值一定不可以被修改呢?
觀察以下一段代碼:
const int i=0;
int *p=(int*)&i;//這裡必須有強制類型轉換
*p=100;
通過強制類型轉換,將地址賦給變量,再作修改即可以改變const常量值。
8. 請分清數值常量和指針常量,以下聲明頗為玩味:
int ii=0;
const int i=0; //i是常量,i的值不會被修改
const int *p1i=&i; //指針p1i所指內容是常量,可以不初始化
int * const p2i=ⅈ //指針p2i是常量,所指內容可修改
const int * const p3i=&i; //指針p3i是常量,所指內容也是常量
p1i=ⅈ //合法
*p2i=100; //合法
const幾點用法
2005年 01月08日
面向對象是C++的重要特性.
但是c++在c的基礎上新增加的幾點優化也是很耀眼的
就const直接可以取代c中的#define
以下幾點很重要,學不好後果也也很嚴重
const
1. 限定符聲明變量只能被讀
const int i=5;
int j=0;
...
i=j; //非法,導致編譯錯誤
j=i; //合法
2. 必須初始化
const int i=5; //合法
const int j; //非法,導致編譯錯誤
3. 在另一連接文件中引用const常量
extern const int i; //合法
extern const int j=10; //非法,常量不可以被再次賦值
4. 便於進行類型檢查
用const方法可以使編譯器對處理內容有更多了解。
#define I=10
const long &i=10; /*dapingguo提醒:由於編譯器的優化,使
得在const long i=10; 時i不被分配內存,而是已10直接代入
以後的引用中,以致在以後的代碼中沒有錯誤,為達到說教效
果,特別地用&i明確地給出了i的內存分配。不過一旦你關閉所
有優化措施,即使const long i=10;也會引起後面的編譯錯誤。*/
char h=I; //沒有錯
char h=i; //編譯警告,可能由於數的截短帶來錯誤賦值。
5. 可以避免不必要的內存分配
#define STRING "abcdefghijklmn
"
const char string[]="abcdefghijklm
";
...
printf(STRING); //為STRING分配了第一次內存
printf(string); //為string一次分配了內存,以後不再分配
...
printf(STRING); //為STRING分配了第二次內存
printf(string);
...
由於const定義常量從匯編的角度來看,只是給出了對應的內存地址,
而不是象#define一樣給出的是立即數,所以,const定義的常量在
程序運行過程中只有一份拷貝,而#define定義的常量在內存中有
若干個拷貝。
6. 可以通過函數對常量進行初始化
int value();
const int i=value();
dapingguo說:假定對ROM編寫程序時,由於目標代碼的不可改寫,
本語句將會無效,不過可以變通一下:
const int &i=value();
只要令i的地址處於ROM之外,即可實現:i通過函數初始化,而其
值有不會被修改。
7. 是不是const的常量值一定不可以被修改呢?
觀察以下一段代碼:
const int i=0;
int *p=(int*)&i;
p=100;
通過強制類型轉換,將地址賦給變量,再作修改即可以改變const常量值。
8. 請分清數值常量和指針常量,以下聲明頗為玩味:
int ii=0;
const int i=0; //i是常量,i的值不會被修改
const int *p1i=&i; //指針p1i所指內容是常量,可以不初始化
int * const p2i=ⅈ //指針p2i是常量,所指內容可修改
const int * const p3i=&i; //指針p3i是常量,所指內容也是常量
p1i=ⅈ //合法
*p2i=100; //合法
關於C++中的const關鍵字的用法非常靈活,而使用const將大大改善程序的健壯性,參考了康建東兄的const使用詳解一文,對其中進行了一些補充,寫下了本文。
1. const常量,如const int max = 100;
優點:const常量有數據類型,而宏常量沒有數據類型。編譯器可以對前者進行類型安全檢查,而對後者只進行字符替換,沒有類型安全檢查,並且在字符替換時可能會產生意料不到的錯誤(邊際效應)
2. const 修飾類的數據成員。如:
class A
{
const int size;
…
}
const數據成員只在某個對象生存期內是常量,而對於整個類而言卻是可變的。因為類可以創建多個對象,不同的對象其const數據成員的值可以不同。所以不能在類聲明中初始化const