對於“const int*p”與“int*const p”這兩種宣告方式,相信很多程式設計師都會頭痛。它們兩者之間究竟有什麼不同之處呢?為了加深大家對這兩種宣告方式的理解,下面就先從“const int i”與“int const i”之間的區別談起。
對於 const 關鍵字,相信大家並不陌生,前面的章節也做了相關的說明。對變數來說,const 關鍵字可以限定一個變數的值不允許改變,從而保護被修飾的東西,防止意外修改,在一定程度上可以提高程式的安全性和可靠性。如下面的範例程式碼所示:
const int i=10;
i++;
很顯然,上面的語句“i++”是錯誤的,無法通過編譯,因為 const 修飾的變數 i 是不可以被修改的。然而對於下面的語句:
int const i=10;
i++;
對於語句“i++”,編譯器會報同樣的錯誤提示。由此可見,“const int i”與“int const i”是完全相同的概念,const 與 int 哪個寫在前面都不影響語意,理解這一點很重要。
理解“const int i”與“int const i”之後,繼續來看“const int*p”與“int*const p”這兩種宣告方式,看下面的例子:
int i1 = 10;
int i2 = 20;
const int *p = &i1;
/* 輸出結果是10 */
printf("%dn", *p);
p = &i2;
/* 輸出結果是20 */
printf("%dn", *p);
i2 = 30;
/* 輸出結果是30 */
printf("%dn", *p);
或許這個時候看了上面的範例程式碼,你會有這樣一個疑問:為什麼 p 的值是可以被修改的,它可以重新指向另一個地址呢?
其實回答上面的問題並不難,只要注意如下兩點:
首先,這裡的 const 關鍵字修飾的是整個“*p”,而不是 p。所以這裡的“*p”是不能被賦值的,也就是說我們不能通過“*p”來修改 i2 的值。
其次,p 前並沒有用 const 關鍵字進行修飾,所以 p 是指標變數,能被賦值重新指向另一記憶體地址。也就是說下面的程式碼是合法的:
p = &i2;
i2 = 30;
看到這裡,你也許會更加疑惑:那又該如何使用 const 來修飾 p 呢?
這個時候,我們就要使用“int*const p”這種宣告形式了。很顯然,這裡的 const 是寫在 p 前和 * 號後的,而不是寫在“*p”前的,所以它是用來修飾限定 p 的。如下面的範例程式碼所示:
int i1 = 10;
int i2 = 20;
int *const p = &i1;
/* 輸出結果是10 */
printf("%dn", *p);
/* p=&i2; p不能再這樣重新賦值了,即不能再指向另一個新地址*/
/* 可以通過*p修改i1的值*/
i1 = 30;
/* 輸出結果是30 */
printf("%dn", *p);
從上面的範例程式碼可以看出,通過“int*const p”宣告之後,p 因為有了 const 的修飾,所以只是一個指標常數。因此,這裡的 p 值是不能重新賦值修改的,它只能永遠指向初始化時的記憶體地址。即下面的程式碼是不合法的:
p = &i2; /*p不能再這樣重新賦值了,即不能再指向另一個新地址*/
但是,也正因為這裡的整個“*p”的前面沒有 const 修飾。也就是說,“*p”是變數而不是常數,所以我們可以通過“*p”來修改它所指記憶體 i1 的值。因此,下面的語句是合法的:
i1 = 30;
由此可見,如果關鍵字 const 直接寫在“*p”前,則程式不能修改“*p”,但可以修改 p;如果關鍵字 const 直接寫在 p 前,則程式不能修改的是 p,但可以通過“*p”來修改它所指記憶體的值。理解這兩點很重要,否則很難掌握“const int*p”與“int*const p”兩者之間的根本區別。
在了解“const int*p”與“int*const p”兩者之間的區別之後,為了鞏固大家的理解,繼續看下面的範例:
const int i=10;
int *p;
/* 強制型別轉換*/
p= (int *) &i;
printf("*p=%dn",*p)
/*這種賦值是合法的*/
*p=20;
printf("i=%dn",i);
printf("*P=%dn",*p);
在上面的程式碼中,因為 const int 型別的 i 的地址是不能賦值給指向 int 型別地址的指標 p 的(否則 p 豈不是能修改i的值)。因此下面的語句是不合法的:
p = &i;
但是,可以通過強制型別轉換進行賦值,因此下面的這種賦值方法是合法的:
p= (int *) &i;
*p=20;
但值得注意的是,儘管可以通過強制型別轉換進行賦值,也不能通過“*p=20”來修改 i 的值。因此,“printf("i=%dn”,i)”輸出的結果是 10,並不是 20。
範例執行結果為:
*p=10
i=10
*p=20