Pointer - declaration - const


const 顧名思義就是不可被改變的意思。

const int a = 10;

也意味著 a 在消失之前就是 10 了。

結合指標應用可提升code的可讀性以及效率。

考慮以下code

int a = 10;
int * p1 = &a;
const int * p2 = &a;
int * const p3 = &a;

p1 應該是沒有什麼問題,我們來看 p2 如何解讀

我們考慮 const int, *p2 . 這三個要素告訴我們 - p2 是個指向 const int 的指標。

也就是說*p2 的型態是 const int .

這也告訴我們 *p2 無法修改, *p2 = 30 是一個違法的語法,縱使 a 根本不是一個 const。

用擬人化的說法就是 - p2 以為他指向的物件是一個常數。

而這邊要提醒的是 - p2 本身並非常數,p2 本身可以被改變。

p3 方面,我們應該 int*, const , p3 這樣看。p3 是一個常數指標,指向int

這告訴我們 p3 無法被改變,但是 *p3 可以.

應用


最常使用到 point to const 的莫過於在使用 function 時傳遞參數了。例如說

void show(int * a, int size)
{
    int i = 0;
    for (i = 0; i < size; ++i)
        printf("%d ", a[i]);
}

這個 function很清楚的他只是要印東西而已。邏輯上我們不應該去改變 a 的內容。 而 show "有權" 改變 a 的內容。

那我們考慮另外一個情況 - 假設 show 被包在一個 dll 或是某個 libs 裡面,我們使用其他人的 function,對使用者而言只可知道他的prototype 是 void show(int * a, int size)

那我們在使用時是否會擔心傳進去的東西會被改變?

而 const 的使用也有助於 complier 最佳化。

另外一個例子是 struct

typedef struct Buffer
{
    int val[1024];
    int size;
} Buffer;

int sumBuffer(Buffer buf)
{
    int i = 0;
    int sum = 0;
    for (i = 0; i < buf.size; ++i)
        sum += buf.val[i];
    return sum;
}

Buffer是一個簡易的 buffer,size是目前使用了多少。

這段 code 用意是將 buffer內的值全部相加並回傳,乍看之下一點問題也沒有,也應該可以work。

然而最大的問題是效率。

sizeof(Buffer) 應該是一個相當大的數字,然後 C 是 call-by-value 的做法,因此會複製一個 buf 來操作。但是在這邊一點必要也沒有。

事實上我們只要將 function 修改為

int sumBuffer(const Buffer * buf)
{
    int i = 0;
    int sum = 0;
    for (i = 0; i < buf->size; ++i)
        sum += buf->val[i];
    return sum;
}

這樣就可以就可提升效率。

results matching ""

    No results matching ""