C语言高频面试题——指针函数和函数指针的区别

在 C 语言中,指针函数函数指针 是两个容易混淆的概念,但它们的功能和用途完全不同。以下是详细的对比分析,帮助你彻底理解它们的区别。


1. 指针函数(Function Returning a Pointer)

定义
  • 指针函数 是一个返回值为指针类型的函数。
  • 它本质上是一个普通函数,只是其返回值是指向某种数据类型的指针。
语法
c 复制代码
type* functionName(parameters);
  • type*:返回值类型是指针。
  • functionName:函数名。
  • parameters:函数的参数列表。
特点
  1. 返回值是一个指针。
  2. 可以通过返回的指针访问或修改内存中的数据。
  3. 常用于动态内存分配、字符串操作等场景。
示例
c 复制代码
#include <stdio.h>

// 指针函数:返回一个指向整型的指针
int* getMaxPointer(int* a, int* b) {
    return (*a > *b) ? a : b;
}

int main() {
    int x = 10, y = 20;
    int* ptr = getMaxPointer(&x, &y); // 返回指向较大值的指针
    printf("Max value: %d\n", *ptr);  // 输出 20
    return 0;
}
使用场景
  • 动态分配内存并返回指针:

    c 复制代码
    int* allocateMemory(int size) {
        return malloc(size * sizeof(int));
    }
  • 返回数组或字符串的一部分:

    c 复制代码
    char* getSubstring(char* str, int start, int len) {
        char* result = malloc(len + 1);
        strncpy(result, str + start, len);
        result[len] = '\0';
        return result;
    }

2. 函数指针(Pointer to Function)

定义
  • 函数指针 是一个指向函数的指针变量。
  • 它存储的是函数的入口地址,可以通过函数指针调用对应的函数。
语法
c 复制代码
return_type (*pointer_name)(parameter_types);
  • return_type:函数的返回值类型。
  • (*pointer_name):函数指针的名称。
  • parameter_types:函数的参数类型列表。
特点
  1. 存储的是函数的地址。
  2. 可以通过函数指针调用函数。
  3. 常用于回调函数、函数表、动态选择函数等场景。
示例
c 复制代码
#include <stdio.h>

// 两个简单的函数
int add(int a, int b) {
    return a + b;
}

int subtract(int a, int b) {
    return a - b;
}

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

    // 将函数指针指向不同的函数
    operation = add;
    printf("Add: %d\n", operation(5, 3)); // 输出 8

    operation = subtract;
    printf("Subtract: %d\n", operation(5, 3)); // 输出 2

    return 0;
}
使用场景
  • 回调函数:

    c 复制代码
    void execute(int (*callback)(int, int), int a, int b) {
        printf("Result: %d\n", callback(a, b));
    }
    
    int multiply(int a, int b) {
        return a * b;
    }
    
    int main() {
        execute(multiply, 4, 5); // 输出 20
        return 0;
    }
  • 函数表(如状态机实现):

    c 复制代码
    int add(int a, int b) { return a + b; }
    int subtract(int a, int b) { return a - b; }
    
    int main() {
        int (*operations[2])(int, int) = {add, subtract};
        printf("Add: %d\n", operations[0](5, 3));       // 输出 8
        printf("Subtract: %d\n", operations[1](5, 3)); // 输出 2
        return 0;
    }

3. 核心区别总结

特性 指针函数 函数指针
定义 返回值为指针的函数 指向函数的指针变量
语法 type* functionName(parameters) return_type (*pointer_name)(parameters)
本质 普通函数,返回指针 存储函数地址,用于调用函数
使用场景 动态内存分配、返回复杂数据结构 回调函数、函数表、动态选择函数
示例 int* getMaxPointer(int* a, int* b) int (*operation)(int, int);

4. 示例对比

指针函数
c 复制代码
char* getString() {
    static char str[] = "Hello, World!";
    return str;
}

int main() {
    char* message = getString();
    printf("%s\n", message); // 输出 "Hello, World!"
    return 0;
}
函数指针
c 复制代码
void greet() {
    printf("Hello!\n");
}

int main() {
    void (*funcPtr)() = greet; // 函数指针指向 greet
    funcPtr(); // 调用 greet 函数
    return 0;
}

5. 注意事项

  1. 指针函数

    • 确保返回的指针有效(避免返回局部变量的地址)。

    • 示例错误:

      c 复制代码
      char* getString() {
          char str[] = "Hello"; // 局部变量
          return str; // 错误:返回悬空指针
      }
  2. 函数指针

    • 确保函数指针与目标函数的签名匹配。

    • 示例错误:

      c 复制代码
      int add(int a, int b) { return a + b; }
      void (*funcPtr)() = add; // 错误:签名不匹配

6. 总结

  • 指针函数:一个返回指针的函数,重点在于返回值。
  • 函数指针:一个指向函数的指针变量,重点在于调用函数。
相关推荐
Lee川7 小时前
优雅进化的JavaScript:从ES6+新特性看现代前端开发范式
javascript·面试
Lee川10 小时前
从异步迷雾到优雅流程:JavaScript异步编程与内存管理的现代化之旅
javascript·面试
晴殇i12 小时前
揭秘JavaScript中那些“不冒泡”的DOM事件
前端·javascript·面试
绝无仅有13 小时前
Redis过期删除与内存淘汰策略详解
后端·面试·架构
绝无仅有13 小时前
Redis大Key问题排查与解决方案全解析
后端·面试·架构
AAA梅狸猫14 小时前
Looper.loop() 循环机制
面试
AAA梅狸猫14 小时前
Handler基本概念
面试
Wect14 小时前
浏览器缓存机制
前端·面试·浏览器
掘金安东尼15 小时前
Fun with TypeScript Generics:玩转 TS 泛型
前端·javascript·面试
掘金安东尼15 小时前
Next.js 企业级落地
前端·javascript·面试