C 語言程式設計教學:指標 (Pointer)

PUBLISHED ON JUL 12, 2018 — PROGRAMMING

指標 (pointer) 是 C (或 C++) 中用來管理記憶體的語法特性,指標內儲存的值是記憶體的位置 (address)。一般學 C (或 C++) 時產生的陰影一部分就是來自於指標,但指標其實並不是什麼洪水猛獸,使用一陣子就會自然而然地習慣其使用方式。

如果了解 C 語言中記憶體的層次,也會對指標有幫助。在 C 語言中,記憶體有三個層次:

  • static:用於全域變數 (global variable)
  • stack:用於局部變數 (local variable)
  • heap:為動態記憶體 (dynamic memory)

註:heap memory 和 heap 結構是兩種不同的東西,請勿搞混。

前兩者會自動釋放,heap memory 則需手動管理。

註:本文僅說明指標最基本的使用法,後續文章會說明其他指標使用的的情境。

宣告和使用指標

以下的例子使用到 stack memory,所以不需手動釋放記體體:

#include <stdlib.h>

int main(void) {
    // An automatic variable using stack memory.
    int i = 3;
    
    // Declare a pointer to int.
    int *i_p = NULL;
    
    // Point to the address of i.
    i_p = &i;
    
    return 0;
}

首先,我們宣告並指派變數 i,程式已經配置好一塊 stack memory。

接著我們宣告一個指向整數的指標 i_p,宣告的方式是在變數旁加上星號 *;以本例來說,i_p 是一個指標,指向整數。如果宣告指標時沒有要將該指標指向某個位址,最好先將其值設為 NULL

在本例中,我們將 i_p 的位址指向 i 所在的位址,對變數 i 前加上 & 可以取得其位址。

如果我們用 Valgrind 檢查此程式,可發現此程式沒有從 heap 分配記憶體,也沒有造成記憶體洩露。

像以下的例子有配置 heap memory,就需手動釋放:

#include <stdlib.h>

int main()
{
    // Allocate a chunk of heap memory.
    int *i_p = malloc(sizeof(int));
    if (!i_p) {
        return EXIT_FAILURE;
    }
    
    // Free i_p.
    free(i_p);
    
    return 0;
}

配置記憶體的函式為 malloc,配置時需傳入記體體的大小,通常是搭配 sizeof 來取得某個型別的大小。平常練習時 malloc 大概都會成功,但其實 malloc 有可能會失敗,最好還是加入錯誤檢查的程式。在本例中,當 malloc 失敗時就中止程式,並回傳程式失敗的狀態碼。

釋放記憶體的函式為 free,將指標傳入即可釋放記憶體。處理記憶體的函式位於 stdlib.h 函式庫中。

mallocfree 應當成對出現,每當有用 malloc (或其他同質函式) 配置 heap memory,就要於後續的程式中搭配 free 來釋放記憶體。

如果我們用 Valgrind 檢查此程式,可發現此程式有從 heap 配置記憶體,但已釋放了,沒有造成記憶體洩露。

藉由指標間接修改值</