当前位置: 首页 > news >正文

C语言学习细节|C语言面向对象编程!函数指针如何正确使用

文章目录

  • 1.函数指针定义
  • 2.格式
  • 3.应用
    • 回调函数
    • 动态函数调用
    • 函数的间接调用
  • 4.结构体与函数指针结合

1.函数指针定义

函数指针就是一个指向函数的指针变量,与指向数据的指针不同,函数指针保存的是函数的地址,这使得程序可以动态地调用不同的函数,而无需在编译时确定具体的函数。可以在程序运行时动态得传递和调用不同的函数

2.格式

函数指针的声明格式为:

返回类型(*变量名)(参数列表),其中

例如,如果你有一个返回 int 类型并接受两个 int 类型参数的函数,你可以这样声明指向这种函数的指针:

int (*funcPtr)(int, int);

3.应用

函数指针在C语言中扮演着极其重要的角色,特别是在需要动态决定函数调用时。下面是三个具体的应用场景:

回调函数

在C语言中,回调函数通常用于实现基于事件的编程。例如,在一个图形用户界面库中,可能需要允许用户定义当按钮被点击时执行的动作。以下是一个简单的例子,展示了如何在一个假设的GUI库中使用回调函数来处理按钮点击事件:

#include <stdio.h>//定义函数指针
typedef void (*ButtonClickHandler)();//定义Button结构体
typedef struct Button {char* label; //函数名ButtonClickHandler onClick; //回调函数
} Button;//绑定回调函数
void buttonClick(Button* button) {if (button->onClick != NULL) {printf("Button '%s' clicked.\n", button->label);button->onClick();}
}//具体执行的函数
void handleExit() {printf("Exiting application...\n");
}int main() {Button exitButton = {"Exit", handleExit};buttonClick(&exitButton);return 0;
}

在这个例子中,Button 结构体包含了一个成员 onClick,这是一个指向函数的指针。当按钮被“点击”时(在这个例子中是通过调用 buttonClick 函数模拟),如果设置了 onClick 回调,它就会被调用。

动态函数调用

函数指针允许根据程序的状态或用户的输入动态调用不同的函数。例如,在一个简单的命令行计算器应用中,用户的选择可以决定调用哪个数学运算函数:

#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);char operator;int x = 5, y = 3;printf("Enter operation (+ or -): ");scanf(" %c", &operator);switch (operator) {case '+':operation = add;break;case '-':operation = subtract;break;default:printf("Invalid operation\n");return 1;}printf("Result: %d\n", operation(x, y));return 0;
}

函数的间接调用

函数的间接调用通常用于实现插件架构,其中函数可以在运行时加载和调用。在下面的例子中,我们模拟这种结构,其中函数指针数组用于调用一系列操作:

#include <stdio.h>void start() {printf("Starting the engine...\n");
}void stop() {printf("Stopping the engine...\n");
}void restart() {printf("Restarting the engine...\n");
}int main() {void (*operations[3])() = {start, stop, restart};for (int i = 0; i < 3; i++) {operations[i]();}return 0;
}

在这个例子中,我们定义了一个函数指针数组 operations,其中包含三个不同的操作:启动、停止和重启。通过遍历数组,我们可以间接调用这些函数。

4.结构体与函数指针结合

在C语言中,结构体与函数指针结合使用可以模拟面向对象编程中的类和方法。结构体可以包含指向函数的指针,允许结构体"实例"具有操作这些数据的"方法"。这是实现模块化和封装设计的一种方式。

例如,可以定义一个表示几何形状的结构体,该结构体包括函数指针,用于计算面积和周长:

typedef struct Shape {int (*getArea)(struct Shape*);int (*getPerimeter)(struct Shape*);int width;int height;
} Shape;int rectangleArea(Shape* s) {return s->width * s->height;
}int rectanglePerimeter(Shape* s) {return 2 * (s->width + s->height);
}void createRectangle(Shape *s, int width, int height) {s->width = width;s->height = height;s->getArea = rectangleArea;s->getPerimeter = rectanglePerimeter;
}int main() {Shape rect;createRectangle(&rect, 5, 10);printf("Area: %d\n", rect.getArea(&rect));printf("Perimeter: %d\n", rect.getPerimeter(&rect));return 0;
}

在这个例子中,Shape 结构体模仿了一个简单的"类",其中包含数据成员(宽度和高度)和作为其"方法"的函数指针。这种方式在设计需要封装数据和功能的模块时非常有用。

文章结构上参考了B站up主:【五分钟解决方案】函数指针如何正确使用
算是终于弄明白了函数指针了,至于指针函数,就把它理解为返回一个指针的函数,其实和别的函数没有任何区别,唯一需要注意的就是别返回一个临时变量的指针即可。
在一个在C++中往往会使用function和bind来实现,代码更加简洁优雅直观
扩展阅读:
C++语法|可调用对象与function类型
C++语法|bind和function解析并实现一个简易线程池
C++语法|bind1st和bind2nd的用法

相关文章:

C语言学习细节|C语言面向对象编程!函数指针如何正确使用

文章目录 1.函数指针定义2.格式3.应用回调函数动态函数调用函数的间接调用 4.结构体与函数指针结合 1.函数指针定义 函数指针就是一个指向函数的指针变量&#xff0c;与指向数据的指针不同&#xff0c;函数指针保存的是函数的地址&#xff0c;这使得程序可以动态地调用不同的函…...

C语言简要(一)

总得让她开心吧 helloworld #include <stdio.h>int main() {printf("hello world!\n");return 0; } 程序框架 #include <stdio.h> int main {return 0; }输出 printf("hello world!\n"); "里面的内容叫做“字符串”&#xff0c;prin…...

那些年我与c++的叫板(一)--string类自实现

引子&#xff1a;我们学习了c中的string类&#xff0c;那我们能不能像以前数据结构一样自己实现string类呢&#xff1f;以下是cplusplus下的string类&#xff0c;我们参考参考&#xff01; 废话不多说&#xff0c;直接代码实现&#xff1a;&#xff08;注意函数之间的复用&…...

二刷算法训练营Day08 | 字符串(1/2)

今日任务&#xff1a; 344.反转字符串 541. 反转字符串II卡码网&#xff1a;54.替换数字 151.翻转字符串里的单词卡码网&#xff1a;55.右旋转字符串 详细布置&#xff1a; 1. 344. 反转字符串 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 …...

使用高防IP是应对网络安全的重要措施

使用高防IP&#xff08;High Defense IP&#xff09;在现代网络环境中显得尤为重要&#xff0c;这主要源于以下几个方面的原因&#xff1a; 一、网络安全形势严峻 随着互联网的快速发展&#xff0c;网络安全问题日益突出。各种网络攻击手段层出不穷&#xff0c;如分布式拒绝服…...

代码随想录-算法训练营day40【动态规划03:整数拆分、不同的二叉搜索树】

代码随想录-035期-算法训练营【博客笔记汇总表】-CSDN博客 第九章 动态规划part03● 343.整数拆分 ● 096.不同的二叉搜索树 详细布置 今天两题都挺有难度&#xff0c;建议大家思考一下没思路&#xff0c;直接看题解&#xff0c;第一次做&#xff0c;硬想很难想出来。343. 整数…...

MySQL数据库中基本数据管理操作

使用SQL语句实现基本数据管理操作——即DML语句 1.添加数据 insert into 表名&#xff08;字段名称&#xff0c;字段名称&#xff0c;字段名称&#xff09;values&#xff08;数据&#xff0c;数据&#xff0c;数据&#xff09; 在MySQL数据库中&#xff0c;除了数字&#x…...

记录一下Hql遇到的零碎问题

建表相关 -- 地区维度表 drop table dim_province_full; create table dim_province_full( id string comment 编号, name string comment 省份名称, region_id string comment 大区id, area_code string comment 行政区位码, iso_code string comment 国际编码, iso_3166_2 s…...

Flutter 中的 TextField 小部件:全面指南

Flutter 中的 TextField 小部件&#xff1a;全面指南 在 Flutter 中&#xff0c;TextField 是一个允许用户输入文本的小部件。它非常灵活&#xff0c;支持多种文本输入场景&#xff0c;如单行文本、多行文本、密码输入、数值输入等。TextField 还提供了丰富的定制选项&#xf…...

GPT-4o:全面深入了解 OpenAI 的 GPT-4o

GPT-4o&#xff1a;全面深入了解 OpenAI 的 GPT-4o 关于 GPT-4o 的所有信息ChatGPT 增强的用户体验改进的多语言和音频功能GPT-4o 优于 Whisper-v3M3Exam 基准测试中的表现 GPT-4o 的起源追踪语言模型的演变GPT 谱系&#xff1a;人工智能语言的开拓者多模式飞跃&#xff1a;超越…...

2024中国应急(消防)品牌巡展西安站成功召开!惊喜不断

消防品牌巡展西安站 5月10日&#xff0c;由中国安全产业协会指导&#xff0c;中国安全产业协会应急创新分会、应急救援产业网联合主办&#xff0c;陕西消防协会协办的“一切为了安全”2024年中国应急(消防)品牌巡展-西安站成功举办。该巡展旨在展示中国应急&#xff08;消防&am…...

信创电脑|暴雨新增兆芯KX-7000处理器版本

IT世界 5 月 15 日消息&#xff0c;暴雨公司信创家族新上架了一款搭载兆芯KX-7000系列处理器、摩尔线程8GB 显卡、16G DDR5 内存以及 512G SSD 的新配置台式电脑主机。 兆芯 KX-7000 处理器采用开先的 8 核 Chiplet互联架构&#xff0c;最高频率3.7 GHz&#xff0c;拥有 32MB 的…...

面向对象 07:抽象类相关知识,抽象类的基本概念,使用方式,以及一些注意事项

一、前言 记录时间 [2024-05-15] 系列文章简摘&#xff1a; 面向对象 03&#xff1a;类与对象的创建、初始化和使用&#xff0c;通过 new 关键字调用构造方法&#xff0c;以及创建对象过程的内存分析 面向对象 04&#xff1a;三大特性之——封装&#xff0c;封装的含义和作用&a…...

Rust中的链式调用方法

在Rust编程语言中&#xff0c;链式调用是一种流行的编程模式&#xff0c;它允许开发者以流畅、连续的方式调用多个方法。这种风格不仅提高了代码的可读性&#xff0c;而且使得复杂的操作可以串联在一起&#xff0c;形成一个清晰、简洁的语句。在Rust中&#xff0c;链式调用主要…...

xCode升级后: Library ‘iconv2.4.0’ not found

报错信息&#xff1a; targets 选中 xxxNotification: Build Phases ——> Link Binary With Libraries 中&#xff0c;移除 libiconv.2.4.0.tbd libiconv.2.4.0.dylib 这两个库&#xff08;只有一个的移除一个就好&#xff09;。 然后重新添加 libiconv.tbd 修改完…...

SQL语言:完整性约束

完整性约束 数据完整性是指存储在数据库中的数据要能正确反映实际情况&#xff0c;规定输入的数据不能是无效值、错误值 或者乱码等。 一、非空约束&#xff1a; 非空约束关键字&#xff1a; not null 1、非空约束的创建 create table teacher( t_id int not null, -- 为教…...

UBUNTU下CMAKE指定执行文件运行时查找库的路径

在Ubuntu下&#xff0c;使用CMake时&#xff0c;如果需要指定执行文件运行时库的搜索路径&#xff0c;可以在CMakeLists.txt文件中通过set_target_properties命令来设置。 以下是一个示例&#xff0c;假设你的目标是一个名为my_application的可执行文件&#xff0c;你想要添加…...

WHAT - CSS Animationtion 动画系列(四)- 移动端全屏动画

目录 一、背景1.1 GIF & Video1.2 存在的问题 二、技术方案2.1 使用CSS动画和JavaScript2.2 使用JavaScript库2.3 使用序列帧1. css animation 帧动画2. JavaScript requestAnimationFrame 帧动画 2.4 使用Canvas1. html 和 canvas 中的 video2. 基于Canvas的动画库 今天我…...

springboot004网页时装购物系统

springboot004网页时装购物系统 亲测完美运行带论文&#xff1a;获取源码&#xff0c;私信评论或者v:niliuapp 运行视频 包含的文件列表&#xff08;含论文&#xff09; 数据库脚本&#xff1a;db.sql其他文件&#xff1a;ppt.pptx论文/文档&#xff1a;开题报告.docx论文&…...

海外住宅IP介绍

住宅IP&#xff0c;通俗的来讲就是分配给家庭的IP地址&#xff0c;ISP默认分配用户为家庭用户&#xff0c;其真实性与安全性都有一定保障。海外住宅IP是指由海外互联网服务提供商分配给家庭用户的IP地址&#xff0c;IP地址通常是静态的&#xff0c;稳定的&#xff0c;可以为用户…...

Office Custom UI Editor:终极指南:如何彻底改造你的Office工作界面?

Office Custom UI Editor&#xff1a;终极指南&#xff1a;如何彻底改造你的Office工作界面&#xff1f; 【免费下载链接】office-custom-ui-editor Standalone tool to edit custom UI part of Office open document file format 项目地址: https://gitcode.com/gh_mirrors/…...

【亲测免费】 PLC1200四路抢答器程序:打造高效公平的抢答体验

PLC1200四路抢答器程序&#xff1a;打造高效公平的抢答体验 【下载地址】PLC1200四路抢答器程序 本仓库提供了一个完整的S7-1200四路抢答器程序&#xff0c;可以直接下载并使用。该程序适用于需要进行四路抢答的场景&#xff0c;如竞赛、培训等。程序经过精心设计和测试&#x…...

Magisk:重新定义Android系统定制边界的技术框架

Magisk&#xff1a;重新定义Android系统定制边界的技术框架 【免费下载链接】Magisk The Magic Mask for Android 项目地址: https://gitcode.com/GitHub_Trending/ma/Magisk Magisk作为Android系统定制领域的革命性框架&#xff0c;以其独特的"无系统"&#…...

波动率交易神器volatility-trading:基于Euan Sinclair理论的完整工具集

波动率交易神器volatility-trading&#xff1a;基于Euan Sinclair理论的完整工具集 【免费下载链接】volatility-trading A complete set of volatility estimators based on Euan Sinclairs Volatility Trading 项目地址: https://gitcode.com/gh_mirrors/vo/volatility-tr…...

Linux|操作系统|zfs文件系统的使用详解

一、 前言概述 书接上回&#xff0c;https://zskjohn.blog.csdn.net/article/details/160741859 Linux|操作系统|最新版openzfs编译记录&#xff0c;上文将zfs文件系统编译安装完毕了&#xff0c;也做了一些总结&#xff0c;但总结的不够全面&#xff0c;本文在做一些补充&am…...

第二章:Compose入门—声明式UI编程

第二章&#xff1a;Compose 入门 — 声明式 UI 编程 Compose 的核心理念&#xff1a;用 Kotlin 代码声明 UI&#xff0c;而不是用 XML 布局文件。 2.1 传统 View 系统 vs Compose 对比项传统 View 系统Jetpack ComposeUI 描述XML 布局文件Kotlin 代码状态更新findViewById 手…...

别被“逻辑“吓退了,入门级数字化认证根本不需要你是学霸

很多人一听到“数字化认证”“AI考试”“逻辑题”&#xff0c;脑子里立刻浮现两种画面&#xff1a;一种是数学特别强的人在刷题&#xff0c;另一种是自己看不懂专业词&#xff0c;直接劝退。可真到企业实习、岗位转型、项目落地时你会发现&#xff0c;职场需要的往往不是“学霸…...

iPhone/iPad移动端CircuitPython嵌入式开发实战指南

1. 项目概述&#xff1a;当嵌入式开发遇上移动生产力作为一名在嵌入式硬件和创客领域折腾了十多年的老玩家&#xff0c;我经历过各种开发环境的变迁。从早年抱着一台厚重的笔记本电脑在实验室里调试&#xff0c;到后来用树莓派做便携式开发机&#xff0c;我一直希望能有一种更轻…...

ansys 2021r1明明已经卸载了,但是开始菜单还存在一些图标,这个是什么原因?是没有卸载干净吗?-需要重新开始菜单卸载。

ansys 2021r1明明已经卸载了,但是开始菜单还存在一些图标,这个是什么原因?是没有卸载干净吗? 开始菜单残留图标通常不是因为软件未卸载干净,而是快捷方式文件未被自动删除‌。即使ANSYS 2021 R1已通过控制面板或自带卸载程序完全移除,其在“开始菜单”中的快捷方式仍可能…...

MXFP混合精度注意力机制优化LLM推理性能

1. 低比特MXFP混合精度注意力机制解析在大型语言模型(LLM)推理过程中&#xff0c;自注意力机制的计算开销一直是主要瓶颈。传统FP16/BF16精度计算虽然能保证模型质量&#xff0c;但存在显著的内存带宽浪费和计算资源利用率不足问题。MXFP&#xff08;Microscaling Floating-Poi…...