const分別在c和c++語言裡的含義和實現機制
2013-07-02 09:14:31 收藏
const的含義
簡單地說:const在c語言中表示唯讀的變數,而在c++語言中表示常量.
c語言const是constant的縮寫,是恆定不變的意思,也翻譯為常量,但是很多人都認為被const修飾的值都是常量,其實這是不精確的.因為,精確來說應該是唯讀的變數,其值在編譯的時候不能被使用,因為編譯器在編譯的時候不知道其儲存的內容.或許當初這個關鍵字應該被替換為readonly.
c語言中const定義的變數只是給出了對應的記憶體位址,而不是像#define一樣給出的是立即數,所以,const定義的唯讀變數在程式執行過程中只有乙個備份(因為它是全域性的唯讀變數,存放在靜態區),而#define定義的巨集變數在記憶體中有若干個備份.
c++語言:
const是c++中常用的型別修飾符,常型別是指使用型別修飾符const說明的型別,常型別的變數或物件的值是不能被更新的.
c++引入const的初始目的是為了取代預編譯指令,消除他的缺點,同時繼承它的優點.《缺點:只是簡單值和**的替代,缺乏型別的檢測機制,安全性不好;優點有三:1.避免意義模糊的數字出現,清晰程式語義2.方便引數的調整和修改,3.提高程式執行效率,因為不需要為常量分配空間》
問題出來了:為什麼const能取代預定義語句?
1. 首先,以const修飾的變數和物件具有不可變性,這是它能取代預定義語句的基礎.
2. 第二,很明顯,它同樣能避免意義模糊的數字定義,也可以方便地進行引數的調整與修改.
3. 第三,c++編譯器通常不為普通const常量(普通是指內建型別,不包括結構體等型別)分配儲存空間,只是把它們儲存在符號表中(注意:c語言中則會為const變數分配儲存空間),這使得它們成為了編譯期間的常量,沒有了儲存和讀記憶體的操作,使得它的效率非常高,同時,也是它能取代預定義語句的重要基礎.
4. 最後,const定義也能像普通的變數定義一樣,它會由編譯器對它進行型別的安全檢查,消除了預定義語句帶來的安全隱患.
我們使用一張表來總結const的作用:
no.作用
說明參考**
1可以定義const常量
const int max = 100;
2便於進行型別檢查
const常量有資料型別,而巨集常量沒有資料型別。編譯器可以對前者進行型別安全檢查,而對後者只進行字元替換,沒有型別安全檢查,並且在字元替換時可能會產生意料不到的錯誤
void f(const int i)
//對傳入的引數進行型別檢查,不匹配進行提示
3可以保護被修飾的東西
防止意外的修改,增強程式的健壯性。
void f(const int i)
//如果在函式體內修改了i,編譯器就會報錯
4可以很方便地進行引數的調整和修改
同巨集定義一樣,可以做到不變則已,一變都變
5為函式過載提供了乙個參考
class a
//乙個函式
void f(int i) const //上乙個函式的過載
......};6
可以節省空間,避免不必要的記憶體分配
const定義常量從彙編的角度來看,只是給出了對應的記憶體位址,而不是象#define一樣給出的是立即數,所以,const定義的常量在程式執行過程中只有乙份拷貝,而#define定義的常量在記憶體中有若干個拷貝
#define pi 3.14159 //常量巨集
const doulbe pi=3.14159; //此時並未將pi放入rom中
......
double i=pi; //此時為pi分配記憶體,以後不再分配!
double i=pi; //編譯期間進行巨集替換,分配記憶體
double j=pi; //沒有記憶體分配
double j=pi; //再進行巨集替換,又一次分配記憶體!
7提高了效率
編譯器通常不為普通const常量分配儲存空間,而是將它們儲存在符號表中,這使得它成為乙個編譯期間的常量,沒有了儲存與讀記憶體的操作,使得它的效率也很高
const的實現機制
const究竟是如何實現的呢?對於宣告為const的內建型別,例如int,short,long等等,編譯器會如何實現const的本意?那麼對於非內建型別是否也是與內建資料型別一樣處理呢,例如對於結構體型別則會怎樣處理呢?下面通過幾個小例子來說明這些問題:
c語言const示例:
const int i=10;
int *p=(int *)(&i);
*p=20;
printf("i=%d *p=%d \n",i,*p);
猜一猜輸出結果是什麼? i=20 *p=20
c++語言const示例1:
const int i=10;
int *p=const_cast(&i);
*p=20;
cout<
輸出結果是 i=10 *p=20
c++語言const示例2:
struct test
};int main(int argc, char* argv)
{const struct test t1;
int *q=(int *)(&t1.j);
*q=40;
cout<
輸出結果是 j=40 *q=40
示例結果分析
看到上面三組輸出結果,我們可以分析兩個問題:
問題1:c語言和c++語言中的const究竟表示什麼?
問題2:const的實現機制究竟是怎樣的?
問題1,對於const int型別的變數i,c語言中通過指標p修改了值後,i變成了20;而在c++中,通過指標p修改了值後,i仍然是10。
問題2,c++語言中 const struct test的元素j通過指標q被改變了,為何const int 與 const struct test的反應機制不同?
針對問題1,我們知道c語言中const表示唯讀的變數,既然把const看成是變數,那麼其在記憶體中就會有儲存他的空間,並且可以通過指標間接的改變該記憶體空間的值,當通過指標p改變該記憶體中的值後,再獲取i的值的時候,會訪問該空間,得到的是被改變後的值。而c++把const看做常量,編譯器會使用常數直接替換掉對i的引用,例如cout針對問題2,c++語言中只是對於內建資料型別做常數替換,而對於像結構體這樣的非內建資料型別則不會。因為結構體型別不是內建資料型別,編譯器不知道如何直接替換,因此必須要訪問記憶體去取資料,而訪問記憶體去取資料必然會取到被指標q改變後的值,因此會造成與c++中const int型別完全不一樣的處理模式。
const分別在C和C 語言裡的含義和實現機制
簡單地說 const在c語言中表示唯讀的變數,而在c 語言中表示常量.c語言const是constant的縮寫,是恆定不變的意思,也翻譯為常量,但是很多人都認為被const修飾的值都是常量,其實這是不精確的.因為,精確來說應該是唯讀的變數,其值在編譯的時候不能被使用,因為編譯器在編譯的時候不知道其儲...
const分別在C和C 語言裡的含義和實現機制
const的含義 簡單地說 const在c語言中表示唯讀的變數,而在c 語言中表示常量.c語言const是constant的縮寫,是恆定不變的意思,也翻譯為常量,但是很多人都認為被const修飾的值都是常量,其實這是不精確的.因為,精確來說應該是唯讀的變數,其值在編譯的時候不能被使用,因為編譯器在編...
? 分別在C 中得意思
表示判斷是否為空 比如我們常用得三元表示式 var a a?b c a如果為空則取b 否則取c 表示空合併運算子 用於定義可空型別和引用型別的預設值。如果此運算子的左運算元不為null,則此運算子將返回左運算元,否則返回右運算元。例如 a b 當a為null時則返回b,a不為null時則返回a本身。...