2011-11-11 33 views
2

對於包含類型爲void foo(const int)的聲明的函數定義以下兩種聲明均有效。我可以在指針類型的聲明中忽略const限定符嗎?

void foo(const int); // valid 
void foo(int); // valid, const can be omitted. 

但是,如果一個函數定義包含類型的聲明void foo(const int*)省略const爲ilegal:

void foo(const int *); // valid declaration 
void foo(int *); // error: const cannot be omitted. 

爲什麼const不能在如果它的參數具有指針類型的函數聲明中省略?什麼改變了?

+0

編譯器產生的錯誤是什麼?你評估的微不足道的反例是int main(int argc,char ** argv); – Erbureth

+0

我使用'int const n'和'int const * ptr'來強調正在發生的事情。 'const'直接應用於它的左邊,除非它是該類型的第一個單詞,在這種情況下,它適用於右邊的東西。當你說'const int * ptr'時,這與'int const * ptr'相同,當從右向左讀時是:「ptr是一個指向const int的指針」。如果你想讓指針本身爲'const',你可以說'int * const ptr'。 「ptr是一個int指針的常量指針」。您可以更改該內存地址的值,但不能更改指向的地址。 –

回答

3

時,它的直接應用向參數只能省略常量符。在指針的情況下,它被應用於被指向的東西,而不是指針本身,所以const和參數之間有一個額外的間接級別。在這種情況下,您可以省略它:

void foo(int* const); 
void foo(int*); 
3

const int x表示x是隻讀的裏面的的功能。外面的世界並不在乎,該函數正在處理一個參數的副本。

但是const int *p意味着p指向某些只讀的內容。外界對確實關心這個;這是一個承諾,指出對象不能被修改。

這樣做的必然結果是,下面的兩個聲明是等價的:

void foo(const int *); 
void foo(const int * const); 
2

函數處理傳遞參數的副本。如果這是整數,則可以省略const,因爲原稿不會被觸摸。在指針到整型的情況下,有三個選擇:

  1. int* p
  2. const int* p(或int const* p
  3. const int* const p(或int const* const p

const可以應用到尖頭物體指針本身或兩者。您作爲參數傳遞的是指針,因此您可以省略const,因爲它的副本將傳遞給函數。所以(2)和(3)可以互換使用(僅在用作函數參數類型時!)。但對於const尖銳物體類型使得差:

  • void foo(const int* p); //函數不能穿過p修改尖整數對象
  • void foo(int* p); //函數可以穿過p修改尖整數對象

在兩種情況下函數可以在函數內修改p,但這些更改不會反映在原始指針的值上。

相關問題