補遺篇之單行道標誌const

    面試時,問及const的含義,很多人會答:"const表示常量",這可不是考英文翻譯,const應該更近似"只讀"而不是常量。
const語法
    對非指針變量,const無論放在類型前或後,都表示變量屬性爲只讀,運行過程中不能也不會賦值修改。如const int a;和int const a;這兩種方式const作用相同,都表示a是一個常整型數。
    而const修飾指針時則有所不同,分三種情況:const int *a; int * const a; const int const * a;
    const int* a表示a是指向只讀整型數的指針,即內存*a中的整數只讀,不能被修改,但指針a可以指向其它地址。

    int* const a;表示a是指向整型數的只讀指針,即:指針指向的整型數可修改,但指針a本身不能修改,不能再指向其他地址。

    const int const * a;表示a是指向只讀整型數的只讀指針,指針指向的整型數不可修改,指針也不可修改。
    有人會有疑問,變量或指針是否修改由程序員自己控制,即使不用const也不影響程序功能實現,爲什麼要引入它呢?
const的作用
    1) const對外傳達有用信息,某變量爲const表明在後續代碼中不會被修改。所以代碼裏合理加入const能提高可讀性,當然前提是要能看得懂這個暗示,否則就是對牛彈琴了。
    2) const能借助編譯器保護那些不希望被改變的變量,防止誤修改。一旦聲明爲const,後面代碼中如果試圖修改,編譯器會報錯提醒。這樣可以減少bug,提高穩定性。
    3) const可以給編譯器一些附加信息,使它產生更高效的優化代碼。編譯器如果知道某變量只讀,值不會改變,就可以利用這一點有針對性做一些優化。
    4) 某些編譯器不支持rwdata段(即不支持全局變量),可用const把全局數據定位到rodata段。另外rodata段的數據可直接在多進程間共享,提高空間利用率且無需同步。
const與常量
    回到開始的問題,const和常量是否一回事?不是。常量沒有存儲空間,是右值。而const的修飾對象依然是左值,有存儲空間,只不過被限定到只讀空間,這和常量有本質不同。C89中左值定義:“對象是一個命名的存儲區域,左值是引用某個對象的表達式”。也就是說有具體存儲空間的對象的表達式,就是一個左值!比如const修飾的變量是左值,而相對的,數組名是右值。
    另外爲防止指針指向的常量被“曲線”修改,C對於指針間賦值有一個規定:左值必須包含右值所有的限定詞。這就限定指向const對象的指針不能賦給指向非const對象的指針,反過來允許。這理所當然,要不,換個指針就能修改原來定義爲const的數據:
    const int *p1 =10;
    int *p2;
    p2 = p1;      //這種賦值被禁止,想來也是,制定C標準不可能留下這麼大個漏洞
    *p2 = 100;

總結:代碼裏看到const就象開車看到了單行道標誌,利用好它會感覺順暢,否則會覺得被束縛。一般來說,只要能確定元素爲只讀,const有益無害。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章