什麼是 Pointer (指標) ?

1
什麼是 Pointer (指標) ?:指標(Pointer)是程式設計中用來儲存記憶體位址的特殊變數類型,能直接操作記憶體位置、實現動態記憶體配置、參考傳遞與高效資料結構。它像「記憶體的門牌號碼」,透過解參考運算子 * 存取位址內的值,是 C/C++ 語言的核心特性,也是理解記憶體管理與效能優化的基礎概念。

什麼是 Pointer (指標) ?

指標(Pointer)是程式設計中用來儲存記憶體位址的特殊變數類型,能直接操作記憶體位置、實現動態記憶體配置、參考傳遞與高效資料結構。它像「記憶體的門牌號碼」,透過解參考運算子 * 存取位址內的值,是 C/C++ 語言的核心特性,也是理解記憶體管理與效能優化的基礎概念。

 

指標的基本概念與語法

記憶體三要素

變數名稱:a(人類可讀名稱)
記憶體位址:&a(實際儲存位置,如 0x7fff5fbff6ac)
變數值:a(儲存內容,如 42)
 

指標宣告

int a = 42;           // 普通整數變數
int *p = &a;          // 指標變數,儲存 a 的位址
int value = *p;       // 解參考:取得 p 指向位址的值(42)
 

指標運算子

  • & 取址運算子:取得變數位址

  • * 解參考運算子:透過位址存取值

  • * 指標宣告:定義指標類型

指標運作原理與記憶體圖解

記憶體布局:
[0x100] [0x104] [0x108] [0x10c]
   42      10       ?       ?
    ↑     ↑
   &a    &b    p → 0x100   *p → 42
 

完整範例

#include <stdio.h>

int main() {
    int a = 42;
    int b = 100;
    int *p = &a;        // p 指向 a
    
    printf("a 值: %d ", a);           // 42
    printf("a 位址: %p ", &a);         // 0x7fff5fbff6ac
    printf("p 值(位址): %p ", p);      // 0x7fff5fbff6ac
    printf("p 指向值: %d ", *p);       // 42
    
    *p = 99;            // 透過指標修改 a
    printf("修改後 a: %d ", a);        // 99
    
    p = &b;             // p 指向 b
    printf("p 新值: %d ", *p);         // 100
    
    return 0;
}
 

指標算術運算

指標支援 +-++--,自動按資料型態大小移動:

int arr[5] = {10, 20, 30, 40, 50};
int *p = arr;  // p = &arr[0]

p + 1     // 移動到 arr[1],位址 + sizeof(int) = +4 bytes
*p + 1    // arr[0] 的值 + 1 = 11
*(p + 1)  // arr[1] 的值 = 20
 

陣列與指標等價

int arr[3] = {1, 2, 3};
int *p = arr;

arr[0] == *p              // 1
arr[1] == *(p + 1)        // 2
arr[2] == *(arr + 2)      // 3
 

指標的實際應用場景

1. 函式參數傳遞(避免複製)

// 傳值:無法修改原變數
void swap_int(int x, int y) {
    int temp = x; x = y; y = temp;
}

// 傳指標:可修改原變數
void swap_int(int *x, int *y) {
    int temp = *x; *x = *y; *y = temp;
}

int main() {
    int a = 1, b = 2;
    swap_int(&a, &b);  // 傳位址
    printf("%d %d ", a, b);  // 2 1
}

 

2. 動態記憶體配置

#include <stdlib.h>

int *create_array(int size) {
    int *arr = malloc(size * sizeof(int));  // 配置記憶體
    for (int i = 0; i < size; i++) {
        arr[i] = i * 10;
    }
    return arr;
}

int main() {
    int *numbers = create_array(5);
    printf("%d ", numbers[2]);  // 20
    free(numbers);  // 釋放記憶體
    return 0;
}

 

3. 字串處理

char *str = "Hello";
char *p = str;

while (*p != '') {  // 遍歷字串
    printf("%c ", *p);
    p++;              // 指標前進
}

 

進階指標類型

指標陣列

int *names[3] = {arr1, arr2, arr3}; // 陣列中每個元素是指標

陣列指標

int (*ptr)[5];  // 指向長度為 5 的整數陣列
int arr[5];
ptr = &arr;     // 指向整個陣列

 

函式指標

int add(int a, int b) { return a + b; }
int (*func_ptr)(int, int) = add;  // 函式指標
printf("%d ", func_ptr(2, 3));   // 5

 

雙重指標

int a = 42;
int *p = &a;
int **pp = &p;     // 指向指標的指標

printf("%d ", **pp);  // 42
 

常見指標陷阱與錯誤

1. 野指標(Dangling Pointer)

int *p = malloc(sizeof(int));
free(p);
*p = 10;  // 錯誤:存取已釋放記憶體

 

2. 空指標解參考

int *p = NULL;
*p = 42;  //  分段錯誤(Segmentation Fault)

 

3. 陣列越界

int arr[3] = {1, 2, 3};
int *p = arr;
printf("%d ", *(p + 10));  // 未定義行為

 

防護措施

int *safe_access(int *p, int index, int size) {
    if (p && index >= 0 && index < size) {
        return p + index;
    }
    return NULL;
}
 

指標在資料結構中的應用

鏈結串列

typedef struct Node {
    int data;
    struct Node *next;
} Node;

Node *head = NULL;
Node *new_node = malloc(sizeof(Node));
new_node->data = 42;
new_node->next = head;
head = new_node;

 

二元樹

typedef struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
} TreeNode;

 

語言別指標特性

語言 指標支援 記憶體安全
C/C++ 直接指標,手動管理 無安全檢查
Rust 智慧指標(Box、Rc) 擁有權檢查
Go 指標,但無指標運算 垃圾回收
Java 無直接指標,引用 自動記憶體管理
Python 無指標,物件引用 自動 GC

 

指標效能優勢

1. 避免複製

// 大結構複製:耗時 O(n)
struct BigData data;
copy_function(data);

// 指標傳遞:O(1)
copy_function(&data);
 

2. 動態大小

int *resize(int *arr, int old_size, int new_size) {
    int *new_arr = realloc(arr, new_size * sizeof(int));
    return new_arr;
}
 

指標賦予程式員對記憶體的直接控制權,是理解低階運作與打造高效資料結構的關鍵。雖然容易出錯(野指標、緩衝區溢位),但正確使用能大幅提升效能與靈活性。現代語言透過智慧指標與擁有權系統解決安全問題,但 C/C++ 的原始指標仍是系統程式設計與效能優化的基礎技能。