S SmartDocs
Série: C++ cpp 205 lignes · Mis à jour 2026-04-03

pointer_arithmetic.cpp

C++/Part1_基礎入門/Ch06_指標與參考/pointer_arithmetic.cpp

// ============================================================
// Ch06 — 指標算術(Pointer Arithmetic)
// 編譯:g++ -std=c++17 -Wall -o pointer_arithmetic pointer_arithmetic.cpp
// ============================================================

#include <iostream>
#include <iomanip>

// ── 函式原型 ──
void printArrayWithPointer(const int* begin, int size);
void reverseArray(int* arr, int size);
int* findMax(int* arr, int size);

// ── 主程式 ────────────────────────────────────────
int main() {
    std::cout << "===== Ch06:指標算術 =====\n\n";

    // ── 1. 指標的遞增與遞減 ──
    std::cout << "【1】指標的遞增與遞減\n";

    int arr[] = {10, 20, 30, 40, 50};
    int* ptr = arr;

    std::cout << "陣列內容:";
    for (int v : arr) std::cout << v << " ";
    std::cout << "\n\n";

    std::cout << "初始 ptr   = " << ptr << ",*ptr = " << *ptr << "\n";

    ptr++;
    std::cout << "ptr++ 後   = " << ptr << ",*ptr = " << *ptr << "\n";

    ptr++;
    std::cout << "ptr++ 後   = " << ptr << ",*ptr = " << *ptr << "\n";

    ptr--;
    std::cout << "ptr-- 後   = " << ptr << ",*ptr = " << *ptr << "\n\n";

    // ── 2. 指標 + 整數 ──
    std::cout << "【2】指標 + 整數\n";

    ptr = arr;  // 重設到開頭
    std::cout << "ptr = arr(指向第一個元素)\n\n";

    for (int i = 0; i < 5; i++) {
        std::cout << "*(ptr + " << i << ") = " << *(ptr + i)
                  << "\t位址 = " << (ptr + i) << "\n";
    }

    std::cout << "\n每次 +1 移動 " << sizeof(int) << " 個位元組(sizeof(int))\n";
    std::cout << "位址差 = " << reinterpret_cast<char*>(ptr + 1) - reinterpret_cast<char*>(ptr)
              << " 位元組\n\n";

    // ── 3. 指標差(Pointer Difference) ──
    std::cout << "【3】指標差\n";

    int* begin = &arr[0];
    int* end   = &arr[4];

    std::cout << "begin 指向 arr[0] = " << *begin << ",位址 " << begin << "\n";
    std::cout << "end   指向 arr[4] = " << *end   << ",位址 " << end << "\n";
    std::cout << "end - begin = " << (end - begin) << "(元素個數差)\n\n";

    // ── 4. 陣列名即指標 ──
    std::cout << "【4】陣列名即指標\n";

    std::cout << "arr       = " << arr << "\n";
    std::cout << "&arr[0]   = " << &arr[0] << "(相同)\n\n";

    std::cout << "arr[i] 等同於 *(arr + i) 的驗證:\n";
    for (int i = 0; i < 5; i++) {
        std::cout << "arr[" << i << "] = " << arr[i]
                  << "\t*(arr + " << i << ") = " << *(arr + i)
                  << "\t&arr[" << i << "] = " << &arr[i]
                  << "\tarr + " << i << " = " << (arr + i) << "\n";
    }
    std::cout << "\n";

    // ── 5. 用指標走訪陣列 ──
    std::cout << "【5】用指標走訪陣列\n";

    int data[] = {5, 15, 25, 35, 45, 55};
    int dataSize = sizeof(data) / sizeof(data[0]);

    // 方法 A:指標遞增
    std::cout << "方法 A(指標遞增):";
    for (int* p = data; p < data + dataSize; p++) {
        std::cout << *p << " ";
    }
    std::cout << "\n";

    // 方法 B:指標 + 索引
    std::cout << "方法 B(指標+索引):";
    for (int i = 0; i < dataSize; i++) {
        std::cout << *(data + i) << " ";
    }
    std::cout << "\n\n";

    // ── 6. 指標比較 ──
    std::cout << "【6】指標比較\n";

    int* p1 = &arr[1];
    int* p2 = &arr[3];

    std::cout << "p1 指向 arr[1]=" << *p1 << ",p2 指向 arr[3]=" << *p2 << "\n";
    std::cout << "p1 <  p2 ? " << (p1 < p2  ? "是" : "否") << "\n";
    std::cout << "p1 >  p2 ? " << (p1 > p2  ? "是" : "否") << "\n";
    std::cout << "p1 == p2 ? " << (p1 == p2 ? "是" : "否") << "\n";
    std::cout << "p1 != p2 ? " << (p1 != p2 ? "是" : "否") << "\n\n";

    // ── 7. 不同型別的指標步進 ──
    std::cout << "【7】不同型別的指標步進大小\n";

    char    charArr[3]   = {'A', 'B', 'C'};
    int     intArr[3]    = {1, 2, 3};
    double  dblArr[3]    = {1.0, 2.0, 3.0};

    char*   cp = charArr;
    int*    ip = intArr;
    double* dp = dblArr;

    std::cout << std::left;
    std::cout << std::setw(10) << "型別" << std::setw(8) << "大小" << "步進位元組\n";
    std::cout << std::setw(10) << "char"
              << std::setw(8) << sizeof(char)
              << reinterpret_cast<char*>(cp + 1) - reinterpret_cast<char*>(cp)
              << "\n";
    std::cout << std::setw(10) << "int"
              << std::setw(8) << sizeof(int)
              << reinterpret_cast<char*>(ip + 1) - reinterpret_cast<char*>(ip)
              << "\n";
    std::cout << std::setw(10) << "double"
              << std::setw(8) << sizeof(double)
              << reinterpret_cast<char*>(dp + 1) - reinterpret_cast<char*>(dp)
              << "\n\n";

    // ── 8. 函式中使用指標操作陣列 ──
    std::cout << "【8】函式中使用指標操作陣列\n";

    int numbers[] = {3, 7, 1, 9, 4, 6, 2, 8, 5};
    int numSize = sizeof(numbers) / sizeof(numbers[0]);

    std::cout << "原始陣列:";
    printArrayWithPointer(numbers, numSize);

    // 找最大值
    int* maxPtr = findMax(numbers, numSize);
    std::cout << "最大值 = " << *maxPtr
              << "(在索引 " << (maxPtr - numbers) << ")\n";

    // 反轉
    reverseArray(numbers, numSize);
    std::cout << "反轉後  :";
    printArrayWithPointer(numbers, numSize);
    std::cout << "\n";

    // ── 9. 重要提醒 ──
    std::cout << "【9】指標算術的注意事項\n";
    std::cout << "1. 指標算術只在陣列(連續記憶體)中有意義。\n";
    std::cout << "2. 不要對不相關的指標做差或比較。\n";
    std::cout << "3. 指標越界是未定義行為(UB)。\n";
    std::cout << "4. 允許指向「最後元素之後一個位置」用於迴圈邊界,\n";
    std::cout << "   但不能解參考。\n";
    std::cout << "5. 現代 C++ 優先使用範圍 for 或迭代器,\n";
    std::cout << "   指標算術主要用於底層操作或效能關鍵路徑。\n";

    return 0;
}

// ── 函式定義 ──────────────────────────────────────

// 用指標走訪印出陣列
void printArrayWithPointer(const int* begin, int size) {
    const int* end = begin + size;
    for (const int* p = begin; p < end; p++) {
        std::cout << *p;
        if (p + 1 < end) std::cout << ", ";
    }
    std::cout << "\n";
}

// 用雙指標法反轉陣列
void reverseArray(int* arr, int size) {
    int* left  = arr;
    int* right = arr + size - 1;

    while (left < right) {
        int temp = *left;
        *left = *right;
        *right = temp;
        left++;
        right--;
    }
}

// 回傳指向最大元素的指標
int* findMax(int* arr, int size) {
    int* maxPtr = arr;
    for (int i = 1; i < size; i++) {
        if (*(arr + i) > *maxPtr) {
            maxPtr = arr + i;
        }
    }
    return maxPtr;
}

Articles liés