Journal Article

指针函数与函数指针:别搞混了

清晰区分C语言中指针函数与函数指针的概念、语法和应用场景,附带完整代码示例。

6 min5 views

指针函数与函数指针:别搞混了

一句话区分

  • 指针函数:返回值是指针的函数(本质是函数)
  • 函数指针:指向函数的指针(本质是指针)

指针函数

指针函数就是一个返回值为指针的函数。

定义格式

c
返回类型 *函数名(参数列表)
{
    // 函数体
    return 指针;
}

示例

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

// 指针函数:返回char*指针
char *create_string(const char *src)
{
    char *str = (char *)malloc(strlen(src) + 1);
    if (str != NULL)
    {
        strcpy(str, src);
    }
    return str;  // 返回指针
}

// 指针函数:返回int*指针
int *find_max(int *arr, int size)
{
    int *max = &arr[0];
    for (int i = 1; i < size; i++)
    {
        if (arr[i] > *max)
        {
            max = &arr[i];
        }
    }
    return max;
}

int main()
{
    char *s = create_string("Hello, World!");
    printf("%s\n", s);
    free(s);

    int nums[] = {3, 1, 4, 1, 5, 9};
    int *p = find_max(nums, 6);
    printf("Max: %d\n", *p);

    return 0;
}

注意事项

c
// 错误示例:返回局部变量的地址
int *bad_function()
{
    int x = 10;
    return &x;  // 危险!x在函数返回后被销毁
}

// 正确示例:返回静态变量或动态分配的内存
int *good_function()
{
    static int x = 10;  // 静态变量,函数返回后仍然存在
    return &x;
}

函数指针

函数指针就是一个指向函数的指针变量。

定义格式

c
返回类型 (*指针名)(参数列表)

示例

c
#include <stdio.h>

// 普通函数
int add(int a, int b)
{
    return a + b;
}

int multiply(int a, int b)
{
    return a * b;
}

// 函数指针作为参数
void calculate(int a, int b, int (*operation)(int, int))
{
    printf("Result: %d\n", operation(a, b));
}

int main()
{
    // 定义函数指针
    int (*func_ptr)(int, int);

    // 指向add函数
    func_ptr = add;
    printf("add: %d\n", func_ptr(3, 5));

    // 指向multiply函数
    func_ptr = multiply;
    printf("multiply: %d\n", func_ptr(3, 5));

    // 直接传递函数指针
    calculate(3, 5, add);
    calculate(3, 5, multiply);

    return 0;
}

实际应用场景

c
// 场景1:回调函数
typedef void (*event_handler)(const char *event, void *data);

void on_click(const char *event, void *data)
{
    printf("Button clicked! Event: %s\n", event);
}

void register_event(const char *event, event_handler handler)
{
    // 注册事件处理函数
    handler(event, NULL);
}

// 场景2:函数表/跳转表
typedef int (*operation_func)(int, int);

int op_add(int a, int b) { return a + b; }
int op_sub(int a, int b) { return a - b; }
int op_mul(int a, int b) { return a * b; }
int op_div(int a, int b) { return a / b; }

// 函数指针数组
operation_func operations[4] = {op_add, op_sub, op_mul, op_div};

// 场景3:qsort排序
int compare_ints(const void *a, const void *b)
{
    return (*(int *)a - *(int *)b);
}

void sort_array(int *arr, int size)
{
    qsort(arr, size, sizeof(int), compare_ints);
}

对比总结

特性指针函数函数指针
本质函数指针
返回值指针任意类型
定义格式int *func()int (*ptr)()
用途返回动态内存、字符串等回调函数、函数表
内存需要管理返回的指针只存储函数地址

容易混淆的写法

c
// 这是指针函数(返回int*的函数)
int *function1(int x)
{
    int *p = malloc(sizeof(int));
    *p = x;
    return p;
}

// 这是函数指针(指向参数为int、返回int的函数的指针)
int (*function2)(int x);

// 这也是函数指针(指向参数为int、返回int*的函数的指针)
int *(*function3)(int x);

// 这是指针函数吗?不是!这是函数指针
int *function4(int x);  // 这是指针函数
int (*function4)(int x); // 这是函数指针

typedef简化

c
// 不用typedef
int (*func_ptr)(int, int);

// 使用typedef简化
typedef int (*MathFunc)(int, int);
MathFunc func_ptr;

// 常见的函数指针类型定义
typedef void (*Callback)(void *data);
typedef int (*CompareFunc)(const void *, const void *);
typedef void (*PrintFunc)(const char *format, ...);

C++中的函数指针

cpp
// C++支持多种定义方式
#include <iostream>
#include <functional>

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

int main()
{
    // 方式1:传统C风格
    int (*ptr1)(int, int) = add;

    // 方式2:使用auto
    auto ptr2 = add;

    // 方式3:使用std::function(推荐)
    std::function<int(int, int)> ptr3 = add;

    // 方式4:使用lambda
    auto ptr4 = [](int a, int b) { return a + b; };

    std::cout << ptr1(3, 5) << std::endl;
    std::cout << ptr2(3, 5) << std::endl;
    std::cout << ptr3(3, 5) << std::endl;
    std::cout << ptr4(3, 5) << std::endl;

    return 0;
}

总结

  • 指针函数是函数,返回指针
  • 函数指针是指针,指向函数
  • 记忆技巧:看*的位置,*跟在函数名后面是指针函数,*跟在括号里是函数指针

掌握这两个概念,对于理解回调函数、事件处理、动态调度等高级编程技巧非常重要。


本文最后更新于2026年7月