const指針,其實是有歧義的稱呼,因為有兩種const修飾法修飾指針,效果不同。
舉個例子:
int x = 1;
const int* p = &x;
這樣的形式,是指針p所指向的對象,被編譯器認為是祗讀的。也就是說,編譯器在編譯時,會認為這裡的指針p所指向的對象x,是不能修改的,但實際上x是否真的不能修改,卻是另一回事(你可以看到,在這個代碼中,x是int而非const int,所以它是可以修改的),編譯器祗負責不讓你寫出類似*p = 0這樣的賦值語句而已,你可以寫x = 0改變對象的值。衹有在聲明const int x = 1時,x才是祗讀的。
另一種修飾語法如下:
程序代码:
char s1[] = "Hello, world!";
char s2[] = "abcd";
char* const p = s1;
const char* q = s1;
這樣的形式,指針s才真的是祗讀的,此時指針的值不可改變,亦即它所指向的地址不可改變,但地址所放置的東西,卻仍然是可能改變的。這個代碼,指針s等於數組s1的入口地址,你在此後,無法寫出s = s2這樣的語句,也無法++p或p++,但是可以*p = 'h'把字符串s1的第一個字符改了。
指針q是上述第一種形式,此時可以++q或q++,寫出putchar(*q++)這樣的語句,輸出'H'之後q向前移動一個字符指向'e'。
對第一種形式,可以用另外一個指針修改對象,如下代碼:
程序代码:
int x = 1;
const int* p = &x;
int* q = &x;
*p = 0; // 非法,編譯不通過
*q = 0; // 合法,編譯通過並可執行成功
指針的一個陷阱,就是像這類用兩個不同的指針指向同一對象造成的。在大型、複雜的程序中,往往指針繁多,程序員自己也忘了到底有多少個指針指向同一個對象,會犯此指針修改了對象而彼指針不知道的錯誤,尤其是釋放堆申請內存的情況,問題更嚴重,假如指針p、q均指向同一塊堆內存,在某個函數調用了free(p),此後某個時刻,調用另一個函數卻使用了*q存取內存數據,那是致命的,根本沒有有效的解決方法——這就是C++引入智能指針的原因,C沒有。
[
本帖最后由 TonyDeng 于 2015-8-22 23:03 编辑 ]