跳转到内容

C 语言函数指针

来自代码酷

模板:Note

函数指针(Function Pointers)概念[编辑 | 编辑源代码]

函数指针是指向函数的指针变量,它存储的是函数的入口地址而非数据。在C语言中,函数名本身就是指向该函数代码的指针。

核心特性[编辑 | 编辑源代码]

  • 允许运行时动态选择调用的函数
  • 可作为参数传递给其他函数(回调机制)
  • 能存储在数组中形成"函数表"
  • 类型安全性:必须匹配返回类型和参数列表

graph LR A[普通指针] -->|指向| B[数据地址] C[函数指针] -->|指向| D[可执行代码]

基本语法[编辑 | 编辑源代码]

声明格式[编辑 | 编辑源代码]

返回类型 (*指针变量名)(参数列表);

示例声明对比

类型 示例
int func(int x);
int (*funcPtr)(int);

初始化与调用[编辑 | 编辑源代码]

#include <stdio.h>

int add(int a, int b) {
    return a + b;
}

int main() {
    // 声明并初始化函数指针
    int (*operation)(int, int) = &add;  // &可选
    
    // 通过指针调用函数
    int result = operation(3, 5);
    printf("3 + 5 = %d\n", result);  // 输出: 3 + 5 = 8
    
    return 0;
}

高级应用[编辑 | 编辑源代码]

回调函数(Callback)[编辑 | 编辑源代码]

函数指针最常见的用途是实现回调机制:

#include <stdio.h>

// 回调函数类型定义
typedef void (*Callback)(int);

void processArray(int arr[], int size, Callback cb) {
    for (int i = 0; i < size; i++) {
        cb(arr[i]);  // 对每个元素调用回调
    }
}

void printElement(int x) {
    printf("%d ", x);
}

void squareElement(int x) {
    printf("%d ", x * x);
}

int main() {
    int nums[] = {1, 2, 3, 4, 5};
    
    printf("Original: ");
    processArray(nums, 5, printElement);
    
    printf("\nSquared: ");
    processArray(nums, 5, squareElement);
    
    return 0;
}

输出

Original: 1 2 3 4 5 
Squared: 1 4 9 16 25

函数指针数组[编辑 | 编辑源代码]

可创建函数指针数组实现状态机或命令模式:

#include <stdio.h>

typedef void (*Command)();

void start() { printf("Starting system...\n"); }
void stop() { printf("Stopping system...\n"); }
void reboot() { printf("Rebooting...\n"); }

int main() {
    Command commands[] = {start, stop, reboot};
    int choice;
    
    printf("Menu:\n1. Start\n2. Stop\n3. Reboot\n> ");
    scanf("%d", &choice);
    
    if (choice >= 1 && choice <= 3) {
        commands[choice - 1]();  // 数组索引从0开始
    }
    
    return 0;
}

复杂类型解析[编辑 | 编辑源代码]

使用typedef简化复杂声明:

// 普通声明
int (*complexPtr)(int (*)(int), int);

// 使用typedef简化
typedef int (*UnaryOp)(int);
typedef int (*BinaryOp)(UnaryOp, int);

BinaryOp simplerPtr;  // 等同于complexPtr

真实案例:qsort函数[编辑 | 编辑源代码]

C标准库中的qsort是函数指针的经典应用:

#include <stdio.h>
#include <stdlib.h>

// 比较函数
int compareInt(const void *a, const void *b) {
    return (*(int*)a - *(int*)b);
}

int main() {
    int arr[] = {5, 2, 8, 1, 4};
    int n = sizeof(arr)/sizeof(arr[0]);
    
    qsort(arr, n, sizeof(int), compareInt);
    
    for (int i = 0; i < n; i++)
        printf("%d ", arr[i]);  // 输出: 1 2 4 5 8
    
    return 0;
}

数学表示[编辑 | 编辑源代码]

函数指针类型可以表示为: F:T1×T2××TnR 其中:

  • Ti 是第i个参数类型
  • R 是返回类型

常见问题[编辑 | 编辑源代码]

页面模块:Message box/ambox.css没有内容。

  • 类型不匹配:参数列表或返回类型不一致
  • NULL指针调用:未初始化就调用
  • 错误转换:强制类型转换可能导致未定义行为

性能考量[编辑 | 编辑源代码]

  • 现代CPU对函数指针调用有良好优化
  • 比switch-case更高效的条件分支实现方式
  • 间接调用可能影响内联优化

扩展阅读[编辑 | 编辑源代码]