【c语言的函数指针介绍】

news2024/11/16 12:57:13

在这里插入图片描述

C语言中的函数指针是一种特殊的指针,它指向函数而不是数据。函数指针允许你在运行时动态地选择要调用的函数,这使得你可以根据需要在不同的函数之间切换,或者将函数作为参数传递给其他函数。函数指针的声明和使用如下:

  1. 声明函数指针: 函数指针的声明形式为returnType (*pointerName)(parameterTypes),其中:

    • returnType是函数返回类型。
    • pointerName是函数指针的名称。
    • parameterTypes是函数参数类型列表。
  2. 赋值函数指针: 将函数的地址赋值给函数指针,以便后续调用该函数。

  3. 使用函数指针: 使用函数指针来调用函数,就像调用函数一样,使用(*pointerName)(arguments)的形式。

以下是一个示例,演示了如何声明、赋值和使用函数指针:

#include <stdio.h>

// 声明一个函数原型
int add(int a, int b) {
    return a + b;
}

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

int main() {
    // 声明函数指针,指向带有两个int参数和int返回值的函数
    int (*functionPtr)(int, int);

    // 将函数地址赋值给函数指针
    functionPtr = add;

    // 使用函数指针调用函数
    int result = (*functionPtr)(10, 5);
    printf("Result of add: %d\n", result);

    // 修改函数指针指向另一个函数
    functionPtr = subtract;
    result = (*functionPtr)(10, 5);
    printf("Result of subtract: %d\n", result);

    return 0;
}

在上述示例中,我们首先声明了两个函数addsubtract,然后声明了一个函数指针functionPtr,它可以指向带有两个int参数和int返回值的函数。我们将functionPtr分别赋值给addsubtract函数的地址,然后使用(*functionPtr)(arguments)的形式来调用这两个函数。通过更改函数指针的赋值,我们可以在运行时选择要调用的函数。

函数指针在一些高级的C编程场景中非常有用,例如回调函数、函数表和动态函数调用。它们允许你在运行时动态决定程序的行为,增加了程序的灵活性和可扩展性。

例子

#include <stdio.h>

// 定义函数指针类型别名
typedef int (*MathOperation)(int, int);

// 函数原型
int add(int a, int b) {
    return a + b;
}

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

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

int divide(int a, int b) {
    if (b != 0) {
        return a / b;
    } else {
        printf("Error: Division by zero\n");
        return 0; // 默认返回0
    }
}

int main() {
    // 定义一个函数指针数组,元素是指向 MathOperation 类型的函数指针
    MathOperation mathOperations[] = {add, subtract, multiply, divide};

    int num1, num2;
    char operator;

    printf("Enter two numbers: ");
    scanf("%d %d", &num1, &num2);

    printf("Enter an operator (+, -, *, /): ");
    scanf(" %c", &operator); // 注意空格以避免吸收上一个输入的换行符

    int choice;

    // 根据用户选择设置choice
    switch (operator) {
        case '+':
            choice = 0;
            break;
        case '-':
            choice = 1;
            break;
        case '*':
            choice = 2;
            break;
        case '/':
            choice = 3;
            break;
        default:
            printf("Invalid operator\n");
            return 1; // 退出程序
    }

    // 使用函数指针数组执行数学操作
    int result = mathOperations[choice](num1, num2);
    printf("Result: %d\n", result);

    return 0;}

例子2

函数指针在回调函数中的常见用法是通过将函数指针作为参数传递给其他函数,以便在需要时执行特定的操作。这种技术通常用于实现回调机制,使得程序可以在运行时动态地指定要执行的函数。以下是一个简单的示例,演示了函数指针在回调函数中的常见用法:

#include <stdio.h>

// 定义一个回调函数类型,该函数接受两个整数参数并返回一个整数
typedef int (*CallbackFunction)(int, int);

// 回调函数1:相加
int add(int a, int b) {
    return a + b;
}

// 回调函数2:相减
int subtract(int a, int b) {
    return a - b;
}

// 执行回调函数的函数
int calculate(int x, int y, CallbackFunction callback) {
    return callback(x, y);
}

int main() {
    int num1 = 10, num2 = 5;
    
    // 使用回调函数1执行加法操作
    int result1 = calculate(num1, num2, add);
    printf("Result of addition: %d\n", result1);

    // 使用回调函数2执行减法操作
    int result2 = calculate(num1, num2, subtract);
    printf("Result of subtraction: %d\n", result2);

    return 0;
}

在上述示例中,我们首先定义了一个回调函数类型CallbackFunction,它接受两个整数参数并返回一个整数。然后,我们实现了两个不同的回调函数addsubtract,它们分别执行加法和减法操作。

接下来,我们定义了一个名为calculate的函数,该函数接受两个整数和一个函数指针作为参数。它使用传递的函数指针来执行特定的操作,并返回结果。

main函数中,我们使用calculate函数两次,一次传递add函数指针,一次传递subtract函数指针,从而实现了不同的数学操作。这就是回调函数的基本思想:将函数指针作为参数传递,以在需要时执行不同的操作,从而增加了程序的灵活性和可扩展性。

这种技术在实际应用中非常有用,例如在图形界面库中,可以通过回调函数允许用户自定义按钮点击后的操作,或者在网络编程中,可以通过回调函数来处理接收到的数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1047770.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

3D孪生场景搭建:模型阵列摆放

阵列摆放概念 阵列摆放是指将物体、设备或元件按照一定的规则和间距排列组合的方式。在工程和科学领域中&#xff0c;阵列式摆放常常用于优化空间利用、提高效率或增强性能。 阵列摆放通常需要考虑间距、角度、方向、对称性等因素&#xff0c;以满足特定的要求和设计目标。不同…

【Element-UI】CUD(增删改)及form 表单验证(附源码)

目录 一、导言 1、引言 2、作用 二、CUD 1、增加修改 1.1、添加弹窗 1.2、定义变量 1.3、定义方法 1.4、完整代码 2、删除 2.1、定义方法 三、表单验证 1、添加规则 2、定义规则 3、提交事件 4、前端完整代码 一、导言 1、引言 增删改是计算机编程和数据库管理…

荣耀时刻!2023抖音电商作者峰会为优质直播间和卓越生态伙伴颁奖

9月27日&#xff0c;抖音电商在上海举行了以“向新成长”为主题的2023抖音电商作者峰会&#xff0c;并现场颁发了荣誉奖项。抖音电商优质直播间以及践行抖音电商作者精神四个维度的年度荣誉一一揭晓。 过去一年&#xff0c;数百万作者与众多品牌商家、MCN机构和精选联盟服务商…

AUTOSAR通信篇 - CAN网络通信(六:CanNm)

文章目录 功能介绍协调算法工作模式网络模式Repeat Message State&#xff08;重复消息状态&#xff09;Normal Operation State&#xff08;正常运行/工作状态&#xff09;Ready Sleep State&#xff08;就绪睡眠状态&#xff09; Prepare Bus Sleep Mode&#xff08;预休眠模…

基于css变量轻松实现网站的主题切换功能

我们经常看到一些网站都有主题切换&#xff0c;例如vue官方文档。那他是怎么实现的呢&#xff1f; 检查元素&#xff0c;发现点击切换时&#xff0c;html元素会动态的添加和移除一个class:dark&#xff0c;然后页面主题色就变了。仔细想想&#xff0c;这要是放在以前&#xff0…

OpenAI宣布ChatGPT支持互联网浏览;GPT-4V(ision)介绍

&#x1f989; AI新闻 &#x1f680; OpenAI宣布ChatGPT支持互联网浏览 摘要&#xff1a;OpenAI宣布ChatGPT现在可以浏览互联网&#xff0c;由微软必应提供支持&#xff0c;并提供直接来源链接。这一功能对于需要最新信息的任务特别有用&#xff0c;如技术研究、购买商品或选…

项目管理:项目经理一定要避开这四大误区

项目经理要保质保量按时达成项目目标&#xff0c;需要关注项目的方方面面&#xff0c;要具有很强的沟通协调能力和目标意识。但是项目经理也不免不了失误&#xff0c;管理中的这四大误区&#xff0c;你经历过几个&#xff1f; 误区一&#xff1a;做不该做的事 你是否遇到这种…

剑指offer32Ⅰ:从上到下打印二叉树

题目描述 从上到下按层打印二叉树&#xff0c;同一层的节点按从左到右的顺序打印&#xff0c;每一层打印到一行。 例如: 给定二叉树: [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 返回其层次遍历结果&#xff1a; [3,9,20,15,7] 提示&#xff1a; 节…

LeetCode每日一题:2251. 花期内花的数目(2023.9.28 C++)

目录 2251. 花期内花的数目 题目描述&#xff1a; 实现代码与解析&#xff1a; 离散化差分 原理思路&#xff1a; 2251. 花期内花的数目 题目描述&#xff1a; 给你一个下标从 0 开始的二维整数数组 flowers &#xff0c;其中 flowers[i] [starti, endi] 表示第 i 朵花的…

pytorch函数reshape()和view()的区别及张量连续性

目录 1.view() 2.reshape() 3.引用和副本&#xff1a; 4.区别 5.总结 在PyTorch中&#xff0c;tensor可以使用两种方法来改变其形状&#xff1a;view()和reshape()。这两种方法的作用是相当类似的&#xff0c;但是它们在实现上有一些细微的区别。 1.view() view()方法是…

【C++】C++继承——切片、隐藏、默认成员函数、菱形

​ ​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;C学习 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 上一篇博客&#xff1a;【C】STL…

行为型设计模式——责任链模式

摘要 责任链模式(Chain of responsibility pattern): 通过责任链模式, 你可以为某个请求创建一个对象链. 每个对象依序检查此请求并对其进行处理或者将它传给链中的下一个对象。 一、责任链模式意图 职责链模式&#xff08;Chain Of Responsibility&#xff09; 是一种行为设…

Uniapp实现APP云打包

一. 基础配置 二. APP图标配置 1. 点击浏览 选取图标(注&#xff1a;图片格式为png) 2. 点击自动生成所有图标并替换 三. 点击发行 并选择云打包 四. 去开发者中心获取证书 我这里是已经获取好的&#xff0c;没有获取的话&#xff0c;按照提示获取即可&#xff0c;非常简单…

axios和vite在本地开发环境配置代理的两种方式,五分钟学会

如果你使用vue或者react开发&#xff0c;就得使用axios吧&#xff0c;然后为了解决跨域问题&#xff0c;就得使用vite配置吧&#xff0c;那怎么协调配置它们两个才能正常工作呢&#xff1f; 正常的流程&#xff1a;配置axios的baseURL&#xff0c;然后配置vite的proxy 第一种…

【论文阅读】Directional Connectivity-based Segmentation of Medical Images

目录 摘要介绍方法效果结论 论文&#xff1a;Directional Connectivity-based Segmentation of Medical Images 代码&#xff1a;https://github.com/zyun-y/dconnnet 摘要 出发点&#xff1a;生物标志分割中的解剖学一致性对许多医学图像分析任务至关重要。 之前工作的问题&…

Linux 实训4 正则表达式

将实训4 &#xff1a;正则表达式的完成情况提交实验报告。 创建并输入文本文件 a bcd 1 233 abc123 defrt456 123abc 12568teids abcfrt568 "Open Source" is a good mechan1sm to develop programs. apple is my favorite food. Football game is not …

数据结构----结构--非线性结构--树

数据结构----结构–非线性结构–树 一.树&#xff08;Tree&#xff09; 1.树的结构 树是一对多的结构 2.关于树的知识点 1.根节点&#xff1a;树最上面的节点 2.中间节点&#xff1a;树中间的节点 3.叶子节点&#xff1a;树最下面的节点 如下图 4.边&#xff1a;在树中…

弱信号的采样与频谱分析(修订中...)

1.频谱混叠效应 - 波形数据抽样 这是一组经过抽样的数据的频谱&#xff0c;红圈圈出的两条谱线&#xff0c;是我们需要关注的特征谱线。这个信号与右侧的临近信号比较&#xff0c;求频率比值&#xff0c;比值恒定与理论推导相符。再5取1降低采样率后&#xff0c;大致相同的频率…

虹科案例 | 虹科MSR实现易碎艺术品安全运输——开发有效减少冲击和振动的新工艺

【案例】在CTI研究项目中使用带有加速度传感器的虹科MSR165数据记录仪对冲击振动进行风险评估 项目背景&#xff1a; 全球艺术品运输量持续增长。在运输过程中&#xff0c;画作面临着诸多压力和风险&#xff0c;如冲击和振动。在博物馆搬运这些画作、装卸包装箱、卡车在颠簸的…

Android 视频通话分析总结

1、WireShark 解析视频流 1.1 安装插件 下载rtp_h264_extractor.lua文件&#xff0c;放入Wireshark安装目录 下载地址&#xff1a;https://download.csdn.net/download/tjpuzm/88381821 在init.lua中添加如下代码 dofile(DATA_DIR.."rtp_h264_extractor.lua") 重新…