指針是 C 語言操作內存、實現高性能算法的核心工具。本文通過直接選擇排序與二分查找兩個經典案例,展示指針算術、解引用、參數傳遞在算法中的實戰運用。
#includevoid select_sort(int *arr, int n) { for (int i = 0; i < n - 1; i++) { int *min_ptr = arr + i; // 指向當前最小元素 for (int j = i + 1; j < n; j++) { if (*(arr + j) < *min_ptr) // 指針解引用比較 min_ptr = arr + j; // 更新最小元素指針 } if (min_ptr != arr + i) { // 需要交換 int tmp = *min_ptr; *min_ptr = *(arr + i); *(arr + i) = tmp; } } } int main() { int a[10] = {12, 2, 37, 67, 90, 1, 78, 67, 2, 32}; printf("Before: "); for (int i = 0; i < 10; i++) printf("%d ", *(a + i)); putchar('\n'); select_sort(a, 10); printf("After: "); for (int i = 0; i < 10; i++) printf("%d ", *(a + i)); putchar('\n'); return 0; }
arr + i 等價於 &arr[i],直接計算地址,無下標轉換開銷*min_ptr 直接訪問值,交換時只需三次解引用int *arr 退化為指針,函數內無法獲取數組長度,必須額外傳 n// 返回找到的元素指針,未找到返回 NULL
int *binary_search(int *arr, int n, int target) {
int *low = arr;
int *high = arr + n - 1;
while (low <= high) {
int *mid = low + (high - low) / 2; // 指針算術:只能相減、加整數
if (*mid == target) return mid;
if (*mid < target) low = mid + 1;
else high = mid - 1;
}
return NULL;
}
int main() {
int a[10] = {2, 4, 5, 13, 15, 20, 30, 35, 40, 50};
int *p = binary_search(a, 10, 20);
if (p) printf("Found %d at index %ld\n", *p, p - a);
else puts("Not found");
p = binary_search(a, 10, 33);
if (p) printf("Found %d\n", *p);
else puts("Not found");
return 0;
}
| 操作 | 合法性 | 結果類型 | 示例 |
|---|---|---|---|
| 指針 + 整數 | ✓ | 指針 | p + 3 |
| 指針 - 整數 | ✓ | 指針 | p - 2 |
| 指針 - 指針 | ✓ (同一數組) | ptrdiff_t (有符號整數) | p2 - p1 = 元素個數 |
| 指針 + 指針 | ✗ | — | 無意義 |
| 指針比較 | ✓ (同一數組) | int | p1 < p2 |
// 交換兩變量值
void swap(int *a, int *b) {
int tmp = *a; *a = *b; *b = tmp;
}
// 返回多個值:最小值、最大值指針
void min_max(int *arr, int n, int **out_min, int **out_max) {
int *min = arr, *max = arr;
for (int i = 1; i < n; i++) {
if (arr[i] < *min) min = &arr[i];
if (arr[i] > *max) max = &arr[i];
}
*out_min = min;
*out_max = max;
}
指針在算法中的核心價值:
p + i、p2 - p1 直觀表達「偏移」與「距離」掌握指針解引用、算術、參數傳遞三板斧,是寫出高性能、可復用 C 算法代碼的關鍵。