常數和變動指標
Const 和 volatile 關鍵字會變更指標的處理方式。 Const 關鍵字指定指標不能修改後初始化; 指標防止之後修改。
volatile關鍵字是表示後面的名稱,與相關的值就可以修改的以外,使用者應用程式的動作。 因此, volatile關鍵字適合用來宣告的多個處理程序或插斷服務常式與通訊所使用的全域資料區域可以存取的共用記憶體中的物件。
當將一個名稱宣告為volatile,編譯器就重新載入記憶體中的值,每次程式存取時。 這大幅減少可能的最佳化。 然而,物件的狀態可能會意外地變更,時以確保可預測的程式效能的唯一方法。
若要宣告為指標所指向的物件 const 或volatile,使用表單的宣告:
const char *cpch;
volatile char *vpch;
若要宣告指標值 — 也就是儲存在指標的實際位址,做為 const 或volatile,使用表單的宣告:
char * const pchc;
char * volatile pchv;
C + + 語言可防止工作分派,會讓物件的修改,或指標宣告為 const。 這類的工作分派會移除一或多個指標被宣告的資訊,因此違反原始宣告的意圖。 以下面的宣告為例:
const char cch = 'A';
char ch = 'B';
指定兩個物件的前面的宣告 (cch,型別的 const char,以及ch,型別的 char),下列宣告/初始化為有效:
const char *pch1 = &cch;
const char *const pch4 = &cch;
const char *pch5 = &ch;
char *pch6 = &ch;
char *const pch7 = &ch;
const char *const pch8 = &ch;
下列宣告/初始設定都是錯誤的。
char *pch2 = &cch; // Error
char *const pch3 = &cch; // Error
宣告的pch2透過此常數的物件可能會修改,因此不允許將指標宣告。 宣告的pch3表示pointer是常數、 非物件。 同樣地,不被允許宣告pch2不允許的宣告。
下列的八個工作分派顯示透過指標指派及變更的指標值,為上述的宣告; 現在,假設 [初始設定是正確的pch1到pch8。
*pch1 = 'A'; // Error: object declared const
pch1 = &ch; // OK: pointer not declared const
*pch2 = 'A'; // OK: normal pointer
pch2 = &ch; // OK: normal pointer
*pch3 = 'A'; // OK: object not declared const
pch3 = &ch; // Error: pointer declared const
*pch4 = 'A'; // Error: object declared const
pch4 = &ch; // Error: pointer declared const
指標宣告為volatile,或以多種 const 和volatile,必須遵守相同的規則。
指向 const 物件通常用在函式宣告,如下所示:
errno_t strcpy_s( char *strDestination, size_t numberOfElements, const char *strSource );
前面的陳述式宣告的函式, strcpy_s,其中三個引數的兩個型別指標的char。 因為參數由參考傳遞引數,而不傳值,此函式應該是免費修改strDestination和strSource如果strSource不宣告為 const。 宣告strSource與 const 可確保呼叫端的strSource無法變更呼叫的函式。
注意事項 |
---|
因為沒有標準轉換是型別名稱* 到 const型別名稱*,是合法傳遞的型別引數的 char * 到 strcpy_s。 然而,反向操作則不行。 沒有隱含轉換可用來移除 const 從物件或指標的屬性。 |
A const 給定型別的指標可指派給相同型別的指標。 但是,變數的指標,並不 const 不能指派給 const 指標。 下列程式碼會顯示正確及不正確的工作分派:
// const_pointer.cpp
int *const cpObject = 0;
int *pObject;
int main() {
pObject = cpObject;
cpObject = pObject; // C3892
}
下列範例會示範如何宣告該物件為 const,如果您有一個物件的指標的指標。
// const_pointer2.cpp
struct X {
X(int i) : m_i(i) { }
int m_i;
};
int main() {
// correct
const X cx(10);
const X * pcx = &cx;
const X ** ppcx = &pcx;
// also correct
X const cx2(20);
X const * pcx2 = &cx2;
X const ** ppcx2 = &pcx2;
}