天天看點

從const int *, int const *, int * const 及const int * const到指針常量、常量指針

問題來由

在C\C++裡的有一個老生常談的問題:關于const限定符與指針符号 * 之間位置關系的不同組合,在代碼中所代表的語義的差異。在了解這些不同概念時,發現有兩個對應的中文翻譯:指針常量和常量指針,大家的了解居然不一緻,甚至是剛好相反。有意思的是,到現在為止,從網上的部落格文章、搜尋詞條,好像也沒有因為這種了解上的差異,生出額外的溝通、代碼成本,大家各自用的都還挺順,實在“詭異”。今天我本着無聊的精神,來分析下為什麼會出現這種現象,及(建議)應該如何統一溝通表述與代碼語義,減少不必要的溝通語義差異所帶來的成本。

const與*的不同位置關系的語義差異

const限定符與解引用符 * 之間不同位置關系所代表的語義,本身并不難了解。具體如下表:

const 與 *  組合文法:

組合 含義
const int * p p(變量)可變,p指向的對象内容不可變
int const * p p(變量)可變,p指向的對象内容不可變
int * const p p(常量)不可變,p指向的對象内容可變
const int * const p p(常量)不可變,p指向的對象内容不可變

由上表可知:

1. const int * p與 int const * p是同義的。

2. const 在 * 左邊時,表示指針所指的對象是常量,不可通過*p解引用方式去更改p所指對象的值。

3. const 在 * 右邊時,表示指針p 是常量,定義時就要賦初始位址,且指針p一直指向該初始位址,不可改變。

常量與指針不同位置關系的表述差異

指針常量與常量指針常常出現了解與表述上混亂,在網上梳理了一下,對指定組合的語義的本質了解應該是一緻的,但在表述時卻存在兩種方式,且剛好相反:

組合一

int a = , b = , c = ;
int * const p = &a; 
p = &b; //編譯錯誤, 不能對p再進行指派(位址)操作
*p = c; //編譯通過,可以對p所指的非常量對象a進行指派操作
           

表述一

此為指針常量,本質是常量,屬偏正短語,指針(的)為形容詞修飾中心名詞常量,是以其完整表述為“指針的常量”, 表示該常量的類型為指針,以此表述來說明該常量的值是一個位址(指針)。

表述二 (推薦)

此為常量指針1(const pointer), 本質是指針,屬偏正短語, 常量(的)為形容詞修飾中心名詞指針, 是以其完整表述為”常量的指針“,以此表述來說明該指針本身為常量。一旦(必須)初始化完成,則它的值(存放在指針中的位址)就不能發生改變了。

組合二

const int a = , b = , c = ;
const int * p = &a; //或寫成“int const * p = &a;” 語義相同
p = &b; //編譯正确, 可以對變量p再進行指派(位址)操作
*p = c; //編譯錯誤,不能對p所指的常量對象a 進行指派操作
           

表述一

此為常量指針,本質是指針,用字首常量來補充說明指針類型,應屬”名+名“的并列短語, 表示一種所屬關系,完整表述為”常量的指針“。以說明該指針指向一個常量,而該指針本身是一個變量,可以對指針重新賦位址。

表述二 (推薦)

此為指向常量的指針2 (pointer to const) , 即組合二的的字面語義表述,簡單直接。該表述偏正短語,由”指向常量的“修飾中心詞”指針“

組合三

const int a = , b = , c = ;
const int * const p = &a; 
p = &b; //編譯錯誤, 不能對常量p再進行指派(位址)操作
*p = c; //編譯錯誤,不能對p所指的常量對象a 進行指派操作
           

表述

此為指向常量的常量指針, 大家對此組合表述差異不大,不做進一步說明。

總結

上述針對典型的幾種組合進行了表述列舉,這其中對同一概念了解的表述混亂,個人了解,這其實應該歸結到使用中文短語時,未按照統一的短語結構來表述各組合對應語義,對同一類詞組是屬并列短語還是偏正短語所引起的了解二義性問題。個人推薦上述各組合的表述二,原因有三:

  1. 按照短語結構統一的标準,兩中組合的表述二均為”偏正短語“,滿足标準。
  2. Bjarne在他的The C++ Programming Language裡面給出過一個助記的方法: 把一個聲明從右向左讀。 而Stanley B. Lippman在他的C++ Primer中同樣給出從右向左讀的建議3。各組中表述二均符合這樣的閱讀順序。
  3. 組合一的表述一“指針常量”的表述,幾大大部頭C\C++經典書籍均未翻譯出現(實際上英文也未發現有pointer const這類表達,不合文法,更正确的應該是pointer to const,表示“指向常量的指針”)。有訛用之嫌,是以并不建議使用。

以上總結,實為愚見,如有纰漏,歡迎指正。

目錄

    • 問題來由
    • const與*的不同位置關系的語義差異
    • 常量與指針不同位置關系的表述差異
      • 組合一
        • 表述一
        • 表述二 (推薦)
      • 組合二
        • 表述一
        • 表述二 (推薦)
      • 組合三
        • 表述
    • 總結
      • 以上總結,實為愚見,如有纰漏,歡迎指正。
      • 目錄
  1. C++ Primer 5th edition, chapter 02, 2.4.2 ↩
  2. C++ Primer 5th edition, chapter 02, 2.4.2 ↩
  3. C++ Primer 5th edition, chapter 02, 2.4.2 ↩

繼續閱讀