Série: C++
cpp
177 lignes
· Mis à jour 2026-06-15
advanced_pointers.cpp
C++/Part1_基礎入門/Ch06_指標與參考/advanced_pointers.cpp
// ============================================================
// Ch06 — 進階指標主題(Advanced Pointer Topics)
// C 風格字串、二維陣列、qsort/std::sort callback、指向成員的指標
// 編譯:g++ -std=c++17 -Wall -o advanced_pointers advanced_pointers.cpp
// ============================================================
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <functional>
#include <string>
// ── 函式原型 ──
void demonstrateCStrings();
void demonstrate2DArray();
void demonstrateQsort();
void demonstrateStdSort();
void demonstratePointerToMember();
// ── 主程式 ────────────────────────────────────────
int main() {
std::cout << "===== Ch06:進階指標主題 =====\n\n";
demonstrateCStrings();
demonstrate2DArray();
demonstrateQsort();
demonstrateStdSort();
demonstratePointerToMember();
return 0;
}
// ── 1. C 風格字串與 char* ──
// C 字串是以 '\0' 結尾的 char 陣列;字串字面量退化為 const char*
void demonstrateCStrings() {
std::cout << "【1】C 風格字串與 char*\n";
const char* msg = "Hello"; // 指向唯讀字串字面量
std::cout << " msg = " << msg << ",長度 = " << std::strlen(msg) << "\n";
// 用指標逐字元走訪,直到遇到 '\0'
std::cout << " 逐字元:";
for (const char* p = msg; *p != '\0'; ++p) {
std::cout << *p << " ";
}
std::cout << "\n";
// 用雙指標反轉可修改的 char 陣列(不使用 <algorithm>)
char buf[] = "ABCDEF";
char* left = buf;
char* right = buf + std::strlen(buf) - 1;
while (left < right) {
char tmp = *left;
*left = *right;
*right = tmp;
++left;
--right;
}
std::cout << " 反轉 \"ABCDEF\" → " << buf << "\n\n";
}
// ── 2. 二維陣列與指標 ──
void demonstrate2DArray() {
std::cout << "【2】二維陣列與指標\n";
int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
// matrix[i][j] 等同 *(*(matrix + i) + j)
std::cout << " matrix[1][2] = " << matrix[1][2]
<< " = *(*(matrix + 1) + 2) = " << *(*(matrix + 1) + 2) << "\n";
// 指向「含 3 個 int 的陣列」的指標
int (*rowPtr)[3] = matrix;
std::cout << " 用 row 指標走訪:\n";
for (int i = 0; i < 2; ++i) {
std::cout << " 第 " << i << " 列:";
for (int j = 0; j < 3; ++j) {
std::cout << rowPtr[i][j] << " ";
}
std::cout << "\n";
}
std::cout << "\n";
}
// ── 3. qsort:C 標準庫排序,以函式指標傳入比較規則 ──
int ascendingCmp(const void* a, const void* b) {
int x = *static_cast<const int*>(a);
int y = *static_cast<const int*>(b);
return (x > y) - (x < y); // 回傳 -1 / 0 / 1
}
int descendingCmp(const void* a, const void* b) {
int x = *static_cast<const int*>(a);
int y = *static_cast<const int*>(b);
return (y > x) - (y < x);
}
static void printArr(const int* arr, int size) {
for (int i = 0; i < size; ++i) std::cout << arr[i] << " ";
std::cout << "\n";
}
void demonstrateQsort() {
std::cout << "【3】qsort(C 風格 callback)\n";
int data[] = {5, 2, 8, 1, 9, 3};
int size = sizeof(data) / sizeof(data[0]);
std::cout << " 原始:";
printArr(data, size);
std::qsort(data, size, sizeof(int), ascendingCmp);
std::cout << " 升序:";
printArr(data, size);
std::qsort(data, size, sizeof(int), descendingCmp);
std::cout << " 降序:";
printArr(data, size);
std::cout << "\n";
}
// ── 4. std::sort:型別安全的現代替代,接受 lambda / functor ──
void demonstrateStdSort() {
std::cout << "【4】std::sort(型別安全 + lambda)\n";
int data[] = {5, 2, 8, 1, 9, 3};
int size = sizeof(data) / sizeof(data[0]);
std::sort(data, data + size, [](int a, int b) { return a < b; });
std::cout << " 升序:";
printArr(data, size);
// 也可用 std::function 儲存比較器
std::function<bool(int, int)> cmp = [](int a, int b) { return a > b; };
std::sort(data, data + size, cmp);
std::cout << " 降序:";
printArr(data, size);
std::cout << "\n";
}
// ── 5. 指向成員的指標(Pointer to Member) ──
struct Calculator {
int value = 0;
int add(int x) { return value + x; }
int multiply(int x) { return value * x; }
};
void demonstratePointerToMember() {
std::cout << "【5】指向成員函式的指標\n";
Calculator calc;
calc.value = 10;
// 宣告指向成員函式的指標:回傳型別 (類別::*名稱)(參數)
int (Calculator::*opPtr)(int) = &Calculator::add;
// 透過物件呼叫用 .*,透過指標呼叫用 ->*
std::cout << " (calc.*opPtr)(5) = " << (calc.*opPtr)(5) << "\n";
Calculator* pc = &calc;
opPtr = &Calculator::multiply;
std::cout << " (pc->*opPtr)(5) = " << (pc->*opPtr)(5) << "\n";
// 成員函式指標陣列:常用於選單 / 狀態機
using MemberOp = int (Calculator::*)(int);
MemberOp ops[] = {&Calculator::add, &Calculator::multiply};
const char* names[] = {"add", "multiply"};
for (int i = 0; i < 2; ++i) {
std::cout << " " << names[i] << "(3) = " << (calc.*ops[i])(3) << "\n";
}
// std::mem_fn 把成員函式包成可呼叫物件
auto fn = std::mem_fn(&Calculator::add);
std::cout << " std::mem_fn add(7) = " << fn(calc, 7) << "\n";
}
Articles liés
C++
c
Mis à jour 2026-07-21
deviceAlpha.h
deviceAlpha.h — c source code from the C++ learning materials (C++/Mavis_Homework/FinalProject/deviceAlpha.h).
Lire l'article →
C++
c
Mis à jour 2026-07-21
finalproject.c
finalproject.c — c source code from the C++ learning materials (C++/Mavis_Homework/FinalProject/finalproject.c).
Lire l'article →
C++
cpp
Mis à jour 2026-07-21
finalproject.cpp
finalproject.cpp — cpp source code from the C++ learning materials (C++/Mavis_Homework/FinalProject/finalproject.cpp).
Lire l'article →
C++
c
Mis à jour 2026-07-21
deviceAlpha.h
deviceAlpha.h — c source code from the C++ learning materials (C++/Mavis_Homework/Lab8/deviceAlpha.h).
Lire l'article →
C++
c
Mis à jour 2026-07-21
lab8.c
lab8.c — c source code from the C++ learning materials (C++/Mavis_Homework/Lab8/lab8.c).
Lire l'article →
C++
cpp
Mis à jour 2026-07-21
lab8.cpp
lab8.cpp — cpp source code from the C++ learning materials (C++/Mavis_Homework/Lab8/lab8.cpp).
Lire l'article →