首页 > 其他分享 >15. C语言 函数指针与回调函数

15. C语言 函数指针与回调函数

时间:2025-01-14 10:01:59浏览次数:3  
标签:15 函数 示例 int C语言 return 函数指针 回调

本章目录:


前言

在 C 语言中,函数指针是一个强大而灵活的工具,它不仅能实现函数的动态调用,还可以通过回调机制大幅降低程序的耦合度。本文将通过通俗易懂的讲解、详细的实例和关键技术点的梳理,帮助你全面掌握函数指针及其在回调函数中的应用。


什么是函数指针?

定义

函数指针是指向函数的指针变量。它允许我们通过指针来调用函数或将函数作为参数传递。

声明方式

以下是函数指针的一种常见声明方式:

typedef int (*fun_ptr)(int, int); // 声明一个指向两个整数参数且返回整数的函数指针类型

函数指针的基本用法

示例:最大值函数

我们来看一个简单的示例,通过函数指针调用 max 函数:

#include <stdio.h>

int max(int x, int y) {
    return x > y ? x : y;
}

int main(void) {
    // 声明函数指针并赋值
    int (*p)(int, int) = max;

    int a, b, c, d;
    printf("请输入三个数字: ");
    scanf("%d %d %d", &a, &b, &c);

    // 使用函数指针调用函数
    d = p(p(a, b), c);

    printf("最大的数字是: %d\n", d);
    return 0;
}
输出示例:
请输入三个数字: 1 2 3
最大的数字是: 3

提示:函数指针在赋值时 & 符号可省略,例如 p = max


回调函数与函数指针

什么是回调函数?

一个回调函数是通过函数指针调用的函数。它通常被用作其他函数的参数,在特定事件发生时被调用。

通俗解释

假设你在商店里需要订购商品。店员会记录下你的电话号码(回调函数),当商品到货时,店员会给你打电话(调用回调函数),然后你去取货(响应事件)。

函数指针 = 电话回调函数名称 = 电话号码


示例:回调函数实现动态数组填充

以下示例演示如何使用函数指针动态填充数组:

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

// 填充数组的函数,第三个参数是函数指针
void populate_array(int *array, size_t arraySize, int (*getNextValue)(void)) {
    for (size_t i = 0; i < arraySize; i++) {
        array[i] = getNextValue();
    }
}

// 回调函数:获取随机值
int getNextRandomValue(void) {
    return rand();
}

int main(void) {
    int myArray[10];
    
    // 使用回调函数填充数组
    populate_array(myArray, 10, getNextRandomValue);

    for (int i = 0; i < 10; i++) {
        printf("%d ", myArray[i]);
    }
    printf("\n");

    return 0;
}
输出示例:
16807 282475249 1622650073 984943658 1144108930 470211272 101027544 1457850878 1458777923 2007237709

进一步探索:带参回调函数

有时回调函数需要接受参数,以下示例展示了如何实现这一功能:

#include <stdio.h>

// 两个整数求和的函数
int sum(int a, int b) {
    return a + b;
}

// 回调函数:对 sum 的结果乘以系数
int sum_with_multiplier(int multiplier, int (*callback)(int, int), int x, int y) {
    return multiplier * callback(x, y);
}

int main(void) {
    // 定义回调函数指针
    int (*callback)(int, int) = sum;

    printf("SUM = %d\n", callback(1, 2));
    printf("SUM with multiplier = %d\n", sum_with_multiplier(2, callback, 1, 2));

    return 0;
}
输出示例:
SUM = 3
SUM with multiplier = 6

函数指针的进阶技巧

函数指针数组

函数指针可以存储在数组中,用于动态选择和调用多个函数:

#include <stdio.h>

void printHello() {
    printf("Hello\n");
}

void printWorld() {
    printf("World\n");
}

int main(void) {
    // 定义函数指针数组
    void (*functions[2])() = {printHello, printWorld};

    // 调用数组中的函数
    functions[0]();  // 输出 "Hello"
    functions[1]();  // 输出 "World"

    return 0;
}

返回函数指针的函数

函数也可以返回一个函数指针:

#include <stdio.h>

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

int (*getAddFunction())(int, int) {
    return add;
}

int main(void) {
    // 获取函数指针
    int (*addFunc)(int, int) = getAddFunction();

    printf("Result: %d\n", addFunc(3, 4));
    return 0;
}
输出示例:
Result: 7

总结

  1. 函数指针 是 C 语言中用来指向函数的特殊指针,它可以调用函数、作为参数传递,并实现动态选择。
  2. 回调函数 是函数指针的核心应用,它通过解耦逻辑提高了代码的灵活性。
  3. 高阶技巧 如函数指针数组、返回函数指针的函数等,为程序提供了更多的动态功能。

掌握函数指针和回调函数,可以让你的 C 语言编程能力迈上一个新台阶!


标签:15,函数,示例,int,C语言,return,函数指针,回调
From: https://blog.csdn.net/wzt001005/article/details/144852186

相关文章

  • 《ESP32-S3使用指南—IDF版 V1.6》第二章 常用的C语言知识点
    第二章常用的C语言知识点1)实验平台:正点原子DNESP32S3开发板2)章节摘自【正点原子】ESP32-S3使用指南—IDF版V1.63)购买链接:https://detail.tmall.com/item.htm?&id=7684993426594)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/esp32/ATK-DNESP32S3.html......
  • 15. 三数之和
    题目这道题着实不知道怎么动笔,看了卡哥思路,很详细,其中的去重小细节讲的非常好,里面讲了两种方法,一种是不太推荐的哈希解法(因为题目要求结果的三元组去重,所以哈希解法不太推荐,但是这个解法我也没太看懂),一种是更推荐的双指针解法。看了卡哥代码敲的:classSolution{public:v......
  • LeetCode:215.数组中的第K个最大元素
    LeetCode:215.数组中的第K个最大元素解题思路看到“第K个最大元素”。考虑选择使用最小堆。解题步骤构建一个最小堆,并依次把数组的值插入堆中。当堆的容量超过K,就删除堆顶。插入结束后,堆顶就是第K个最大元素。leetcode在线运行测试可能是用本地环境跑分...有缓存卡大数有er......
  • C语言初阶习题(2分支语句和循环语句-for)【10】杨辉三角
    1.题目描述——在屏幕上打印杨辉三角。2.思路第一步先尝试打印下三角第二步,分析他们之间的关系3.代码实现#define_CRT_SECURE_NO_WARNINGS1#include<stdio.h>intmain(){ intn=0; scanf("%d",&n); intarr[100][100]={0}; inti=0; in......
  • C语言初阶习题【27】猜名次
    1.题目描述5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果:A选手说:B第二,我第三;B选手说:我第二,E第四;C选手说:我第一,D第二;D选手说:C最后,我第三;E选手说:我第四,A第一;比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。2.思路3.代码实现#include<stdio.h>in......
  • c语言——【linux】多线程编程 (内附练习及代码)
    1:开启一个线程主线程中:使用标准IO,向一个文件中写入任意数据分支线程:使用标准IO,读取该文件中的数据#include<stdio.h>#include<string.h>#include<unistd.h>#include<stdlib.h>#include<sys/types.h>#include<sys/stat.h>#include<fcntl.h>#include<p......
  • LeetCode Top Interview 150 - Stack
    Somescenarioswhereastackistypicallytheappropriatedatastructuretouse:1.ParenthesesMatching:Problemsthatrequirecheckingforbalancedparenthesesorbracketsoftenutilizestackstoensurethateveryopeningbrackethasacorrespondingclo......
  • 高阶C语言|探索指针的根源之目(进阶指针)
    文章目录前言1.字符指针(`char*`)1.1字符串常量与指针1.2字符指针的使用2.数组指针与指针数组2.1指针数组2.2数组指针3.数组与指针传参3.1一维数组传参3.2二维数组传参4.函数指针(`functionpointer`)4.1函数指针的基本用法4.2使用函数指针数组5.指向函数指......
  • C语言-循环结构
    循环结构:重复执行代码1、for循环    循环用于在知道循环次数的情况下使用。三个部分:初始化、条件判断和更新    基本形式:                    嵌套循环:                2、while循环        循环在......
  • P1540 [NOIP2010 提高组] 机器翻译
    题目背景NOIP2010提高组T1题目描述小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章。这个翻译软件的原理很简单,它只是从头到尾,依次将每个英文单词用对应的中文含义来替换。对于每个英文单词,软件会先在内存中查找这个单词的中文含义,如果内存中有,软件就......