指針和const

雖然說指針的運算和操作,考慮到運算符的優先級,能夠執行的加減運算的真正含義,合法的指針範圍等,(請參見《指針的基本操作》),在使用和閱讀他人代碼時,需要仔細注意其中的細節,但是指針的最主要的用途有兩個:

1.  使用指針同函數交換信息: 比如我們希望被調用的函數可以修改調用函數的變量的值,就需要使用指針作爲形參;

2.  使用指針在處理數組的函數之中;


如果我們要處理的形參是如int這樣的基本類型的時候,我們可以直接向函數傳遞數值(值傳遞),只有當我們需要改變傳遞進去變量的值的時候,我們才傳遞指針。


對於處理數組的函數,我們就只能傳遞指針,因爲這樣的效率更高。如果我們通過值向函數傳遞數組,那麼函數中必須分配足夠存放一份原始數組的拷貝的存儲空間,然後把原數組的所有數據複製到這個新數組中去。這樣非常浪費空間和時間資源。


如果我們直接傳遞數組的地址,然後函數可以直接讀寫原數組,這樣的效率就會更高。


但是這樣的話,就類似傳遞int類型參數的指針一樣,存在被調用函數可能修改原數組的可能,那麼我們怎麼保護不需要做任何修改的數組不被改寫呢?

使用const,在形參類表中給傳遞的指針加上const修飾符!


int sum(const int ar[], int n);

像上面聲明和使用,是告訴函數應該把ar所指向的數組當做包含常量的數據的數組對待,不可以對數組內的元素進行改寫。

但需要注意的是,在形參列表中使用const並不是要求原數組是固定不變的,這個const的“常量保護作用”的範圍僅限於在被調用函數不改變傳遞進來的數組。或者說在形參列表裏用const修飾數組對數組的提供的保護,就像用值傳遞可以對基本數據類型提供的保護。


類似的,我們來討論“指向常量的指針”:這種情況和上面的行爲類似。指針本身被const修飾,但是不表示他指向的數據是常量,也不表示這個指針只能指向最初始指向的變量,只表示不能通過指針來修改所指向的數值。

double rates[5] = {88.99, 100.12, 59.45, 183.11, 340.5};

const double * pd = rates;  //pd就是我們要討論的情形

* pd = 29.89;    //不允許,這是通過const修飾的指針改寫所指向的數值

pd[2] = 222.22; //不允許,這同樣是通過const修飾的指針改寫所指向的數值,只是這裏用的是另外一種類似數組的寫法(參見《指針的基本操作》)

rates[0] = 99.99;  //因爲rates本身不是const,可以修改的。

pd++; //允許,這裏讓pd所指向的變量不同了,這是允許改變的。

所以這種情況與上面討論的形參列表情況類似,如果應用在函數形參中,保證函數不會用這個指針來修改數據。

void show_something_only (const double *ar, int n);


既然已經討論到這裏,我們可以繼續研究其他三種形式上類似的情況:

1. 當想要被指向的數據本身就已經是const變量的時候摻和進來的時候:

      如上面討論的const修飾的指針是可以指向本身不是const的變量,但是如果本身變量就是const類型的,那麼只能用有const修飾符修飾的指針來指向它。

      double rates[5] = {88.99, 100.12, 59.45, 183.11, 340.5};

     const  double locked[5] = {0.08, 0.09, 0.07, 0.06, 0.05};

     double * pnc = rates; //允許

     pnc =locked;  //不允許,只有非常量數據才能賦值給普通指針

     pnc= &rates[3]; //允許,



2. 保證指針不指向別的地方的const修飾符;

       double rates[5] = {88.99, 100.12, 59.45, 183.11, 340.5};

     double * const pc = rates;  //注意const出現的位置。初始化時,這個指針pc就指向了rates數組的首元素,這個指針不可以再指向別的地方了

     pc = &rates[2];  //不允許,這裏想要修改指針所指向的地址

     *pc =92.99; //允許,這裏只是想修改指針所指向地址存儲的值;


3. 既保證不更改指針所指向的地址,同時也不修改所指向的數據。

       double rates[5] = {88.99, 100.12, 59.45, 183.11, 340.5};

     const double * const pc = rates;  //注意const出現的位置。初始化時,這個指針pc就指向了rates數組的首元素,這個指針不可以再指向別的地方了

     pc = &rates[2];  //不允許,這裏想要修改指針所指向的地址

     *pc =92.99; //不允許,這裏想修改指針所指向地址存儲的值;












發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章