18. 彻底厘清指针函数与函数指针

指针函数的定义与特征

指针函数本质是返回指针的函数,声明形式为返回类型 *函数名(参数)。例如:

c 复制代码
char *get_string() {  
    char *str = malloc(100);  
    return str; // 返回动态分配的指针  
}  

关键点

  • 函数体需确保返回的指针有效(如动态分配或全局变量地址)。
  • 常见于字符串操作、动态内存管理等场景。

函数指针的定义与特征

函数指针是指向函数入口地址的变量,声明形式为返回类型 (*指针名)(参数)。例如:

c 复制代码
int (*math_op)(int, int); // 声明函数指针  
int add(int a, int b) { return a + b; }  
math_op = add; // 指向add函数  
printf("%d", math_op(2, 3)); // 通过指针调用  

关键点

  • 需匹配目标函数的返回类型和参数列表。
  • 常用于回调机制、策略模式等灵活调用场景。

语法对比与易混淆点

  • 指针函数

    c 复制代码
    int *func(int); // 返回int指针的函数  
  • 函数指针

    c 复制代码
    int (*func)(int); // 指向接受int参数并返回int的函数  

区别

  • 指针函数的*靠近返回类型,函数指针的*被括号包裹。
  • 函数指针需先赋值才能调用,指针函数直接调用即可。

实际应用示例

指针函数示例

c 复制代码
int *create_array(int size) {  
    return malloc(size * sizeof(int));  
}  

函数指针示例

c 复制代码
void sort(int *arr, int size, int (*compare)(int, int)) {  
    // 使用compare指针调用比较函数  
}  

常见错误与规避

  1. 指针函数返回局部变量地址

    c 复制代码
    int *invalid() {  
        int x = 10;  
        return &x; // 错误:x在栈上销毁  
    }  

    修正:返回动态分配或静态存储的地址。

  2. 函数指针类型不匹配

    c 复制代码
    void (*ptr)(char) = strlen; // 错误:strlen签名不匹配  

    修正:确保指针签名与目标函数一致。


总结对比表

维度 指针函数 函数指针
声明重点 int *func() int (*func)()
操作 调用后返回指针 需赋值并调用目标函数
典型用途 资源创建、数据传递 回调、运行时多态

通过语法形式、应用场景和错误案例的对比,可清晰区分两者。核心记忆:指针函数是函数,函数指针是变量