Series: C++
cpp
172 lines
· Updated 2026-06-15
function_pointers.cpp
C++/Part1_基礎入門/Ch06_指標與參考/function_pointers.cpp
// ============================================================
// Ch06 — 函式指標(Function Pointers)
// 編譯:g++ -std=c++17 -Wall -o function_pointers function_pointers.cpp
// ============================================================
#include <iostream>
#include <functional>
#include <string>
#include <vector>
// ── 基本算術函式 ──
int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }
int divide(int a, int b) { return (b != 0) ? a / b : 0; }
// ── 函式原型 ──
void demonstrateBasicFunctionPointer();
void demonstrateFunctionPointerArray();
void demonstrateCallback();
void demonstrateReturnFunctionPointer();
int applyOperation(int a, int b, int (*op)(int, int));
void forEach(int* arr, int size, void (*action)(int&));
void printElement(int& val);
int calculate(int* arr, int size, const std::function<int(int, int)>& op);
void demonstrateStdFunction();
void demonstrateLambdaAsFunctionPointer();
// ── 主程式 ────────────────────────────────────────
int main() {
std::cout << "===== Ch06:函式指標 =====\n\n";
demonstrateBasicFunctionPointer();
demonstrateFunctionPointerArray();
demonstrateCallback();
demonstrateReturnFunctionPointer();
demonstrateStdFunction();
demonstrateLambdaAsFunctionPointer();
return 0;
}
// ── 1. 函式指標基礎 ──
void demonstrateBasicFunctionPointer() {
std::cout << "【1】函式指標基礎\n";
// 宣告:回傳型別 (*指標名)(參數型別列表)
int (*funcPtr)(int, int) = nullptr;
funcPtr = add; // 函式名會自動轉為函式位址
std::cout << "funcPtr = add\n";
std::cout << "funcPtr(3, 5) = " << funcPtr(3, 5) << "\n";
std::cout << "(*funcPtr)(3, 5) = " << (*funcPtr)(3, 5) << "(等價寫法)\n";
funcPtr = multiply;
std::cout << "funcPtr = multiply → funcPtr(4, 6) = " << funcPtr(4, 6) << "\n\n";
}
// ── 2. 函式指標陣列(策略模式雛形) ──
void demonstrateFunctionPointerArray() {
std::cout << "【2】函式指標陣列\n";
int (*operations[])(int, int) = {add, subtract, multiply, divide};
const char* names[] = {"加", "減", "乘", "除"};
int x = 20, y = 4;
for (int i = 0; i < 4; i++) {
std::cout << x << " " << names[i] << " " << y
<< " = " << operations[i](x, y) << "\n";
}
std::cout << "\n";
}
// ── 3. 函式指標作為 callback ──
int applyOperation(int a, int b, int (*op)(int, int)) {
return op(a, b);
}
void forEach(int* arr, int size, void (*action)(int&)) {
for (int i = 0; i < size; i++) {
action(arr[i]);
}
}
void printElement(int& val) {
std::cout << val << " ";
}
void demonstrateCallback() {
std::cout << "【3】函式指標作為 Callback\n";
std::cout << "applyOperation(10, 3, add) = "
<< applyOperation(10, 3, add) << "\n";
std::cout << "applyOperation(10, 3, subtract) = "
<< applyOperation(10, 3, subtract) << "\n";
int data[] = {1, 2, 3, 4, 5};
std::cout << "forEach 印出:";
forEach(data, 5, printElement);
std::cout << "\n\n";
}
// ── 4. 回傳函式指標 ──
int (*selectOperation(char op))(int, int) {
switch (op) {
case '+': return add;
case '-': return subtract;
case '*': return multiply;
case '/': return divide;
default: return add;
}
}
void demonstrateReturnFunctionPointer() {
std::cout << "【4】回傳函式指標\n";
char ops[] = {'+', '-', '*', '/'};
int a = 12, b = 3;
for (char op : ops) {
int (*selected)(int, int) = selectOperation(op);
std::cout << a << " " << op << " " << b
<< " = " << selected(a, b) << "\n";
}
std::cout << "\n";
}
// ── 5. std::function(現代 C++ 替代方案) ──
int calculate(int* arr, int size, const std::function<int(int, int)>& op) {
int result = arr[0];
for (int i = 1; i < size; i++) {
result = op(result, arr[i]);
}
return result;
}
void demonstrateStdFunction() {
std::cout << "【5】std::function(現代替代方案)\n";
int arr[] = {2, 3, 4, 5};
std::cout << "累加 arr = " << calculate(arr, 4, add) << "\n";
std::cout << "累乘 arr = " << calculate(arr, 4, multiply) << "\n";
// 可接受 capturing lambda(函式指標做不到)
int offset = 10;
auto withOffset = [offset](int a, int b) { return a + b + offset; };
std::cout << "帶 offset 的累加 = " << calculate(arr, 4, withOffset) << "\n\n";
}
// ── 6. Lambda 與函式指標的關係 ──
void demonstrateLambdaAsFunctionPointer() {
std::cout << "【6】Lambda 與函式指標\n";
// 無 capture 的 lambda 可轉為函式指標
int (*lambdaPtr)(int, int) = [](int a, int b) { return a * a + b * b; };
std::cout << "lambdaPtr(3, 4) = " << lambdaPtr(3, 4) << "(3² + 4²)\n";
// 有 capture 的 lambda 不能轉為函式指標,需用 std::function
int factor = 2;
// int (*bad)(int, int) = [factor](int a, int b) { return (a + b) * factor; }; // 編譯錯誤
std::function<int(int, int)> good = [factor](int a, int b) {
return (a + b) * factor;
};
std::cout << "std::function + capturing lambda: good(3, 4) = "
<< good(3, 4) << "\n\n";
std::cout << "【7】選擇建議\n";
std::cout << " 函式指標 → C 互操作、零 overhead、效能關鍵路徑\n";
std::cout << " std::function → 需要儲存 callback、接受 lambda / functor\n";
std::cout << " template → 編譯期多型,最佳效能(進階主題)\n";
}
Related articles
C++
c
Updated 2026-07-21
deviceAlpha.h
deviceAlpha.h — c source code from the C++ learning materials (C++/Mavis_Homework/FinalProject/deviceAlpha.h).
Read article →
C++
c
Updated 2026-07-21
finalproject.c
finalproject.c — c source code from the C++ learning materials (C++/Mavis_Homework/FinalProject/finalproject.c).
Read article →
C++
cpp
Updated 2026-07-21
finalproject.cpp
finalproject.cpp — cpp source code from the C++ learning materials (C++/Mavis_Homework/FinalProject/finalproject.cpp).
Read article →
C++
c
Updated 2026-07-21
deviceAlpha.h
deviceAlpha.h — c source code from the C++ learning materials (C++/Mavis_Homework/Lab8/deviceAlpha.h).
Read article →
C++
c
Updated 2026-07-21
lab8.c
lab8.c — c source code from the C++ learning materials (C++/Mavis_Homework/Lab8/lab8.c).
Read article →
C++
cpp
Updated 2026-07-21
lab8.cpp
lab8.cpp — cpp source code from the C++ learning materials (C++/Mavis_Homework/Lab8/lab8.cpp).
Read article →