亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> C语言

C 语言函数指针实战:回调、函数表与 void 指针进阶用法

函数指针赋予 C 语言强大能力,允许函数通过内存地址直接操作数据而非复制值。通过向指针参数传递地址,函数可修改原变量,实现原地交换、动态回调、高阶函数等模式。

函数指针示例

经典 swap 例程演示函数如何通过地址交换两变量值。

void swap (int *a, int *b);
int main() {
    int m = 25;
    int n = 100;
    printf("m is %d, n is %d\n", m, n);
    swap(&m, &n);
    printf("m is %d, n is %d\n", m, n);
    return 0;
}
void swap (int *a, int *b) {
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

输出:

m is 25, n is 100
m is 100, n is 25

C 语言函数指针实战:回调、函数表与 void 指针进阶用法

  1. 声明 swap 接受两个整型指针
  2. main 初始化 m、n 并打印
  3. 调用 swap(&m, &n) 传递地址
  4. swap 内用临时变量交换值
  5. 解引用指针读写实际数据

数组参数函数

数组传参时退化为指针。下例通过指针遍历求和:

int add_array (int *a, int num_elements);
int main() {
    int Tab[5] = {100, 220, 37, 16, 98};
    printf("Total summation is %d\n", add_array(Tab, 5));
    return 0;
}
int add_array (int *p, int size) {
    int total = 0;
    for (int k = 0; k < size; k++) {
        total += p[k]; /* 等价于 total += *p; p++; */
    }
    return total;
}

输出:

Total summation is 471

C 语言函数指针实战:回调、函数表与 void 指针进阶用法

  1. 定义 add_array 接受指针与大小,返回求和
  2. 传入数组名 Tab(退化为指针)及长度

返回数组的函数

函数可返回静态数组指针,适合调用者需要临时数组且不想管理内存的场景。

#include <stdio.h>
int * build_array();
int main() {
    int *a;
    a = build_array(); /* 获取前 5 个整数 */
    for (int k = 0; k < 5; k++) printf("%d\n", a[k]);
    return 0;
}
int * build_array() {
    static int Tab[5] = {1,2,3,4,5};
    return Tab;
}

输出:

1 2 3 4 5

C 语言函数指针实战:回调、函数表与 void 指针进阶用法

  1. 声明返回静态数组指针的函数
  2. 用返回指针遍历打印数组内容

函数指针

函数指针持有函数入口地址,支持动态分发与回调。声明语法需在星号外加括号以免歧义。

return_type (*function_name)(arguments)

示例:通过指针调用例程。

#include <stdio.h>
void Hi_function (int times); /* 函数 */
int main() {
    void (*function_ptr)(int); /* 函数指针 */
    function_ptr = Hi_function; /* 赋值 */
    function_ptr(3); /* 调用 */
    return 0;
}
void Hi_function (int times) {
    for (int k = 0; k < times; k++) printf("Hi\n");
}

输出:

Hi Hi Hi

C 语言函数指针实战:回调、函数表与 void 指针进阶用法

  1. 定义普通函数
  2. 声明匹配签名的函数指针
  3. 将指针指向函数名
  4. 通过指针调用函数

函数指针数组

将多个函数指针存入数组可实现表驱动逻辑,类似 switch 语句。下例演示简易计算器:

#include <stdio.h>
int sum(int num1, int num2);
int sub(int num1, int num2);
int mult(int num1, int num2);
int divi(int num1, int num2);
int main() {
    int x, y, choice, result;
    int (*ope[4])(int, int);
    ope[0] = sum;
    ope[1] = sub;
    ope[2] = mult;
    ope[3] = divi;
    printf("Enter two integer numbers: ");
    scanf("%d%d", &x, &y);
    printf("Enter 0 to sum, 1 to subtract, 2 to multiply, or 3 to divide: ");
    scanf("%d", &choice);
    result = ope[choice](x, y);
    printf("%d", result);
    return 0;
}
int sum(int x, int y) {return x + y;}
int sub(int x, int y) {return x - y;}
int mult(int x, int y) {return x * y;}
int divi(int x, int y) {return y != 0 ? x / y : 0;}

结果: 输入 13 48 2 → 624

C 语言函数指针实战:回调、函数表与 void 指针进阶用法

  1. 定义四个算术函数
  2. 创建四元素函数指针数组,签名一致
  3. 各指针指向对应函数
  4. 获取用户选择并调用选定函数

使用 void 指针的函数

Void 指针提供类型无关的数据访问。用作函数参数时,允许例程接受任意类型,前提是调用者提供正确强转。

void * cube (const void *);

示例程序:

#include <stdio.h>
void* cube (const void* num);
int main() {
    int x = 4;
    int cube_int = (int)cube(&x);
    printf("%d cubed is %d\n", x, cube_int);
    return 0;
}
void* cube (const void *num) {
    int result = (*(int *)num) * (*(int *)num) * (*(int *)num);
    return (void*)result;
}

结果: 4 cubed is 64

C 语言函数指针实战:回调、函数表与 void 指针进阶用法

  1. 定义接受 const void 指针、返回 void 指针的函数
  2. 强转为 int * 访问值
  3. 计算立方并强转回 void * 返回

作为参数的函数指针

将函数指针传给另一函数是常见回调模式。标准库 qsort 即利用此技术排序任意类型数组。

void qsort(void *base, size_t num, size_t width, int (*compare)(const void *, const void *));

排序整型数组示例:

#include <stdio.h>
#include <stdlib.h>
int compare (const void *, const void *);
int main() {
    int arr[5] = {52, 14, 50, 48, 13};
    size_t num = sizeof(arr)/sizeof(arr[0]);
    size_t width = sizeof(arr[0]);
    qsort((void *)arr, num, width, compare);
    for (size_t i = 0; i < num; i++) printf("%d ", arr[i]);
    return 0;
}
int compare (const void *elem1, const void *elem2) {
    int a = *(int *)elem1;
    int b = *(int *)elem2;
    return (a - b);
}

结果: 13 14 48 50 52

C 语言函数指针实战:回调、函数表与 void 指针进阶用法

  1. 实现 compare 返回负/零/正表示两整数大小关系
  2. 用 sizeof 计算数组元素数与元素宽度
  3. 调用 qsort 传入数组、个数、宽度、比较函数
  4. 打印排序后数组验证

C语言

  1. C 语言用户自定义函数四大模式对比:参数与返回值的设计权衡
  2. C++ do-while 循环详解:语法、实战示例与嵌套循环
  3. C++ 指针精通:核心概念、代码示例与实战应用
  4. C++ 运算符重载实战指南:语法、方法、限制与代码示例
  5. C++ 函数详解:从声明到调用的实战指南
  6. C# 集合实战教程:ArrayList、Stack、Queue、Hashtable 等核心类型全解析
  7. C 语言指针完全指南:类型、用法与最佳实践
  8. Python str.count() 完全指南:统计字符与子串出现次数实战
  9. 精通 Python Lambda 函数:实用示例与最佳实践
  10. Python round() 函数详解与实战示例
  11. 精通 Python map() 函数:语法、示例与最佳实践
  12. Python timeit():精准测量代码执行时间与实战示例