函数指针的好处、作用

2023-05-16

C中函数指针的作用  

项目中用到了很多封装在struct中的函数指针,以前在MFC里面经常用到则个作为回调函数,还以为是微软设计的特色呢。在网上查了一下它的用法,做个总结。

 
1)提供调用的灵活性。设计好了一个函数框架,但是设计初期并不知道自己的函数会被如何使用。比如C的”stdlib”中声明的qsort函数,用来对数值进行排序。显然,顺序还是降序,元素谁大谁小这些问题,库程序员在编写qsort的时候不可能决定。这些问题是要在用户调用这个函数的时候才能够决定。那边qsort如何保证通用性和灵活性呢?采用的办法是让函数的使用者来制定排序规则。于是调用者应该自己设计comparator函数,传给qsort函数。这就在程序设计初期保证了灵活性。尽管使用函数指针使得程序有些难懂,但是这样的牺牲还是值得的。
 
2)提供封装性能。有点面向对象编程的特点。比如设计一个栈结构

typedef struct _c_stack{
               int base_size;
               int point;
               int * base;
               int size;
               int  (*pop)(struct _c_stack *);
               int  (*push)(int,struct _c_stack *);
               int  (*get_top)(struct _c_stack);
}c_stack;

在初始化完之后,用户调用这个结构体上的pop函数,只需要s.pop(&s)即可。即使这个时候,工程内部有另外一个函数名字也叫pop,他们之间是不会发生名字上的冲突的。

原因很简单,因为结构体中的函数指针指向的函数名字可能是

int ugly_stupid_no_one_will_use_this_name_pop(c_stack *)
,只是stack的用户是不知道他在调用s.pop(&s),实际上起作用的是这样一个有着冗长名字的函数。

 函数指针这种避免命名冲突上的额外好处对于一些库函数的编写者是很有意义的,因为库可能被很多的用户在许多不同的环境下使用,这样就能有效的避免冲突而保证库的可用性。


 

函数指针的好处

2012-07-07 15:35  912人阅读  评论(0)  收藏  举报
stream struct 编程 file windows

一般的时候用不到,主要还是一个简化结构和程序通用性的问题,也是实现面向对象编程的一种途径。简单的总结为:

1.       实现面向对象编程中的多态性

2.       回调函数


举两个例子:
1. 你现在要实现一个文件系统,但是文件的介质有硬盘和软盘,那么它们各自的读写函数实现肯定是不一样的。
好比  
int a_write(char *data_stream, int LBA);
int b_write(char *data_stream, int LBA);
有一个结构体维护:
typedef int (*write_operation)(char* data, int LBA);
struct {
  write_operation op;
  ...
} file_struct;
最后有一个写函数:
int file_wirte(char *data_stream, int LBA)
{
  return file_struct.op(data_stream, LBA);
}

2. Windows编程中的事件handle函数,即回调函数,在事件队列都是一个函数指针来保存的:
typedef void (*event_handler) (unsigned int para1, unsigned int para2);
struct event {
  unsigned int ev_id;
  event_handler handler;
};

struct event event_queue[MAX_EVENT_SIZE];
程序可以通过扫描这个事件队列来获取每个事件对应的处理函数,然后调用它,即为回调函数。


求解释c语言函数指针的作用

举报|2012-05-11 13:39 823807  |  分类:C/C++  |  浏览1428次

使用函数指针的好处在于,可以将实现同一功能的多个模块统一起来标识,这样一来更
容易后期的维护,系统结构更加清晰。或者归纳为:便于分层设计、利于系统抽象、降低耦合度以及使接口与实现分开

我是初学者,不明白这段话什么意思,求解释  
分享到:
2012-05-11 14:27 提问者采纳

你上面那一段话,对于初学者来说确实坑爹,说的像什么官方话语,我看着也就只能理解个模糊大概。
先给你举个例子吧,函数指针的写法
int *p;
int a;
p=&a; //这是一般整型指针
#include <iostream>
using namespace std;
int arr(int a,int b){return 0;}//比如说是函数1
int brr(int a,int b){return 1;}//比如说是函数2
int main()
{
   int (*frr)(int,int); //这里就是函数指针
	frr =arr; //它可以指向arr
	cout<<frr(1,2)<<endl;
	frr=brr;//也可以指向brr,只需要改改指向的对象,就可以操作不同的函数
	cout<<frr(1,2)<<endl;
	return 0;
}  
评论 | 12 0

qincheng2007 |来自团队美女也开源吧 |七级采纳率49%

擅长:C/C++

其他类似问题

更多关于函数指针的作用的问题>>

网友都在找:

  函数指针的作用
按默认排序|按时间排序

其他2条回答

2012-05-11 14:57 copylegend |五级

好吧,假设你已经知道函数指针的写法和用法。
那么那段话的意思就是, 你有了一只手,可以用来装备并切换武器打怪,比如可以装备刀子,或者装备棍子。当你的武器只有一种或者比较少的时候,可能这只手切换武器的功能不常用到。当到了后期,你的武器多了,那你因为有了这只能装备并切换武器的手,而可以更有效率的打怪。
OVER  
评论(1) | 7 0
2012-05-12 11:20 刘嘉璠 |四级

上面的话是有道理的。只是,要真的体会这些名词,需要你亲历躬行,一个“百度知道”是很难让你真正体会并理解的。国人一些教科书也不负责任,人云亦云的说这些话,但很少能透彻讲解。我小试一下。

1. 便于分层设计:函数指针是引用,是间接层,或曰隔离层。它输出到上层,给上层用户用。函数实体是实现,在下层,给开发者用,实现者(软件工程师)关注。这就是简单的分层的概念了。上层用户想让一个函数所做的东西会变化时,我们只需要改变底层实现,并用函数指针指向新的实现就行了。
再精炼一下分层:分层的核心是对接口进行设计和实现。函数指针的作用就是提供不同实现的统一接口。
2. 利于系统抽象:只有存在多个类似的实体需要模拟、操作或控制时(这种情况很多)才需要抽象。多个类似的实体就是对象,抽象的结果就是类。在C里边,可以用函数指针数组完成这种抽象。如, fopen 就是一个例子。他可以打开文件。C里面将磁盘文件、串口、USB等诸多设备抽象为文件。
3. 降低耦合度以及使接口与实现分开:第1条中的解释已经说明了这一点。
再具体一下:
我曾搭建过一个嵌入式平台。其中的设备操作(硬件驱动)采用了多组函数指针数据,并进行了简单的封装,其结果是:
业务软件使用函数指针数组的封装函数访问设备。这个封装可展示为:
int  DevOpen(char *strDevName);
int  Write(int DevID, char* DataFrom, int StartDevAddr, int  DataLong);
int  Read(int DevID, char* DataTo, int StartDevAddr, int  DataLong);
int  DevClose(int DevID);

这组抽象出来的函数,是一组语义清晰且稳定的上层接口,为上层的业务开发团队使用。底层的驱动层,各自实现自己的设备打开、读、写及关闭代码,然后,注册自己的设备到系统列表里。上层业务接可以使用了。期间的耦合在这里:
int  Write(int DevID, char* DataFrom, int StartDevAddr, int  DataLong)
{
     /* Error detecting.  */
      return DevWrite[ DevID ]( char* DataFrom, int StartDevAddr, int  DataLong );
}

其中,DevWrite[ DevID ]就是一个函数指针数组:
int  (*DevWrite)[ MAX_DEV_NUM ]( char*,int,int ) = {0};
里面放的就是多个设备的写的操作。其中包括:UART,RTC,WatchDog。EEPROM,DigitalInput,DigitalOutput,Key,LCD,LED。
好了。说的太多了。如需要学习,可邮件livefuture@163.com。
但愿对你有所帮助。  


指向函数的指针变量作为函数参数有什么好处?

举报|2008-02-04 14:24 13152448536  |  分类:其他编程语言  |  浏览2313次

书上给了个例子,但还是看不懂有什么好处?
#include<stdio.h>

float add(float x,float y)
{return (x+y);}
float sub(float x,float y)
{return (x-y);}
float mul(float x,float y)
{return (x*y);}
float div(float x,float y)
{return (x/y);}

float result(float x,float y,float(*pf)(float,float))
{
    float s;
    s=(*pf)(x,y);
    return s;
}

void main()
{
    float a,b,s;
    char op;
    printf(""please select your operation (input +,-,*or/)\n");
    scanf("%c",&op);
    printf("please input the two operand\n");
    scanf("%f %f",&a,&b);
    switch(op)
   {
    case '+':s=result(a,b,add);break;
    case '-':s=result(a,b,sub);break;
    case '*':s=result(a,b,mul);break;
    case '/':s=result(a,b,div);break;
    }
    printf("the operation is :%f%c%f=%f\n",a,op,b,s);
}  
分享到:
2008-02-04 23:02 提问者采纳

灵活。
实际上我觉得如果作参数不用指针的话,还真不知道怎么解决。
参数传递一般就是传值和传址两种方式,作为函数的话,好像都想不出怎么传值。
我理解所谓指向函数的指针就是这个函数的入口地址。直接就跳转到那个地址去执行了。  



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

函数指针的好处、作用 的相关文章

  • Gazebo添加模型库,解决打开后无模型的问题

    链接 xff1a http pan baidu com s 1pKaeg0F 密码 xff1a cmxc xff08 来自rosclub cn xff09 或是下载https bitbucket org osrf gazebo models
  • SpringBoot简单增删改查

    SpringBoot简单增删改查crud 学习Spring Boot 逐渐使用Spring Boot开始对spring mvc项目进行提升 Spring Boot相较于spring mvc的代码亮得到了优化 代码更加精简 需要进行的配置更加
  • Cisco 18系列AP在u-boot下tftp启动

    18系列AP在u boot下不能直接启动tar文件 xff0c 需要将tar文件解压得到part bin文件然后才能启动 在u boot下使用bootipq tftp启动镜像 RNAQ C7 bootipq tftp Specified B
  • OpenStack之keystone(T版)

    这里写目录标题 一 概述二 主要功能三 相关概念四 认证流程五 创建虚拟机的过程六 部署一 创建数据库实例和用户二 安装keystone Apache一 配置keystone二 初始化认证服务数据库三 初始化fernet密钥存储库四 配置b
  • OpenStack之Nova(T版)

    目录 一 概述二 Nova系统架构一 API二 Scheduler一 选择计算节点二 调度器类型三 过滤器 三 compute四 conductor五 PlacementAPl六 cell架构 三 部署一 Placement一 创建数据库二
  • 基于FreeRTOS消息缓冲区,实现STM32H7双核之间通信的原理

    FreeRTOS V10 3 1版本已发布 xff0c 官方网站也更新了 xff08 大家可以去看看 xff09 今天给大家分享的是 xff1a 使用FreeRTOS消息缓冲区 xff0c 实现简单的非对称多处理 xff08 AMP xff
  • keil mdk中文乱码,两种解决方法,字体不再难看

    方法一 xff1a 修改成Encode in UTF 8 without signature 我嘞个去 xff01 被字符编码整晕了 xff0c unicode xff0c ANSI xff0c UTF 8 xff0c GB2312 新版m
  • 迪文屏幕T5L平台学习笔记三:定时器使用

    上篇博客介绍了第一个C51程序Demo xff0c 在文本上显示一个 xff08 中英文混合 xff09 字符串 xff0c 这篇博客介绍下定时器2的使用 xff08 定时器0和1类似 xff09 一 先看定时器2的寄存器 在其他章节 xf
  • 使用闲置主机共享资源赚钱教程,收益不知道多少,不知道够不够电费的

    下载网心云的镜像ISO文件 xff0c 使用Rufus将镜像烧到一个U盘中 注意 此操作会清空U盘 xff0c 做完镜像后用U盘启动系统进入安装模式 安装完开机激活就可以了 瞧瞧我的收益 xff0c 1TB硬盘4核2G的工业主机 xff0c
  • 迪文屏幕T5L平台学习笔记七:RS485测试

    由于串口通信距离近 xff0c 且容易受到干扰 xff0c 最近改为RS485通信方案 xff0c 迪文屏幕DMG10600K070 03WTC正好也支持RS485通信 xff0c 把调试过程记录下 1 首先看下数据手册 xff1a 串口5
  • 烧录flash_烧录固件完成后,配置JFLASH让程序自动运行

    问题描述 xff1a 当使用IAR调试Cortex M0 43 产品 xff0c 在IAR MDK调试环境下烧录以后可以正常运行 xff0c 但是如果使用Segger的JFLASH直接烧录固件 bin或者 hex格式二进制文件 后程序并没有
  • 电力网络安全区域概念及划分

    笔者的专栏有很多人询问电力网络安全区的内容 xff0c 加上笔者多年来也一直看得很混乱 xff0c 这次多方收集信息 xff0c 加上自己的理解 xff0c 写成此文 内容可能更符合电网网络结构 xff0c 如有疏漏欢迎到电力知识图谱网站
  • 一文了解DTU、FTU、TTU、RTU的区别

    电力自动化有一堆 某TU xff08 不敢写X 怕被认为新设备 xff09 的设备 xff0c 搞得不做自动化的同学们很晕 xff0c 这里为大家收集下这几者的定义和区别 想要了解更加详细的内容 xff0c 可以点击电力知识图谱网站 xff
  • PIC单片机的配置字总结

    平台为 xff1a MPLAB V8 92 xff0c 这个ID有两个编译选项 xff1a DEBUG和RELEASE xff0c 那么可以根据系统预定宏来自动根据选择模式 xff0c 配置配置字 一 PIC18F系列配置字编写 MUC P
  • USB 2.0 A型、B型、Mini和Micro接口 type-c 定义及封装

    免责声明 xff1a 所有资料均来自互联网 xff0c 如有错误之处 xff0c 本人概不负责 出处 xff1a http blog 163 com wilicedon lee blog static 8158848320101174142
  • 对于嵌入式初学者建议读的书

    刚加入了几个嵌入式群 xff0c 群里提问最多的是怎么能够快速入门 xff1f 对于这个问题 xff0c 一千人个人可能有一千个答案 我也在嵌入式行业里混了几年 xff0c 虽然说技术很水 xff0c 经 验不多 xff0c 但是比起没有入
  • matlab学习笔记二:plot画图怎么设置线条类型和颜色

    出处 xff1a https jingyan baidu com article 48b558e338aaa37f38c09a80 html matlab的绘图功能很强大 xff0c 因此它在科学实验和社会调研中被广泛应用 我们在 绘制图形
  • XModem协议

    出处 xff1a XModem协议 XModem协议介绍 xff1a XModem是一种在串口通信中广泛使用的异步文件传输协议 xff0c 分为XModem和1k XModem协议两种 xff0c 前者使用128字节的数据块 xff0c 后
  • 详解,N沟道MOS管和P沟道MOS管

    出处 xff1a P沟道mos管作为开关的条件 xff08 GS gt GS xff08 TH xff09 xff09 1 P沟道mos管作为开关 xff0c 栅源的阀值为 0 4V xff0c 当栅源的电压差为 0 4V就会使DS导通 x
  • python通过pip安装torch错误及解决办法ERROR: Could not find a version that satisfies the requirement torch

    错误代码 pip install torch 61 61 1 6 0 43 cu101 to rchvision 61 61 0 7 0 43 cu101 f https download pytorch org whl torch sta

随机推荐

  • 智能代码补全工具 tabnine

    安装方法链接 xff1a https www tabnine com install 亲测有效 xff1a tabnine vim Without Vundle Run git clone depth 1 https github com
  • ovsdb <7> OVSDB操作实践及各种机制的分析

    4 2OVSDB操作实践及各种机制的分析 在安装了上述的openvswitch和做了相应的配置之后 xff0c 下面对openvswitch中提供的各种ovsdb的工具 操作方式和工作机制做一些简单的说明 xff1a 1 Ovsdb ser
  • ovsdb <10> Ops-cli结合ovsdb部分流程及接口分析

    4 6Ops cli结合ovsdb部分流程及接口分析 Ops中对于ovsdb的应用主要是基于上述的ovsdb的简单用法上的一个扩展和函数封装 xff0c 现在就其与之前不同的地方做补充说明并就各个函数的使用做相应的说明 根据前面的ovsdb
  • 项目管理:代码检查 pre-commit 使用详解

    Git钩子脚本对于在提交代码审查之前识别简单问题很有用 我们在每次提交时都运行钩子 xff0c 以自动指出代码中的问题 xff0c 例如缺少分号 xff0c 尾随空白和调试语句 通过在代码审阅之前指出这些问题 xff0c 代码审阅者可以专注
  • SOCAT详解

    概述 socat xff0c 是linux下的一个工具 xff0c 其功能与有 瑞士军刀 之称的netcat类似 xff0c 不过据说可以看做netcat的加强版 的确如此 xff0c 它有一些netcat所不具备却又很有需求的功能 xff
  • sonic 架构学习

    射人先射马 xff0c 擒贼先擒王 在我们学习sonic的过程中 xff0c 无疑了解sonic的架构是非常重要的 xff0c 然后再去了解各个模块的细节 xff0c 总分学习模式 下面是我自我学习并翻译的链接https github co
  • 以配置MTU 了解SONIC网络操作系统命令配置流程

    介绍 总览 本文档介绍了SONiC中的最大传输单元 xff08 MTU xff09 配置和行为 在计算机网络中 xff0c 层的通信协议的MTU定义了允许该层通过一个接口传输的最大协议数据单元的大小 xff08 以字节为单位 xff09 每
  • Mellanox CX4 offload 卸载功能介绍

    无状态功能卸载 cx4支持多种类型的无状态卸载 xff0c 如下面列表所示 Checksum OffloadLarge Send OffloadsReceive Side ScalingTransmit Side ScalingInterr
  • Mellanox cx4 驱动总结

    以下要点总结了基本的以太网驱动程序流程 xff1a 驱动加载 通过命令 QUERY HCA CAP 检查以太网卸载支持的设备功能建立发送rings 分配中断 xff0c 创建Event Queues 和 Completion Queues
  • 希腊符号读法大全

    是希腊字母 的古典写法 xff0c 读偏导数 xff0c 读round 1 alpha a lf 阿尔法 角度 xff1b 系数 2 beta bet 贝塔 磁通系数 xff1b 角度 xff1b 系数 3 gamma ga m 伽马 电导
  • 遍历ip开放的端口

    用于检测服务器上某个ip地址开放的端口 xff0c 查漏洞等 bin bash port range to check for i in 20 25 do echo now is i check open port and save to
  • Linux字符设备注册函数 register_chrdev详解

    Linux字符设备注册函数 register chrdev 详解 当我们需要注册字符设备的时候 xff0c 需要 module init 中调用 register chrdev 注册 下面主要介绍接口的实现过程与细节 内核函数前面添加 代表
  • phy基础知识总结 common register总结

    PHY篇 以太网PHY标准寄存器分析 PHY 是IEEE802 3中定义的一个标准模块 xff0c STA xff08 station management entity xff0c 管理实体 xff0c 一般为MAC或CPU xff09
  • linux 命令行下查看 html 和 pdf 文件方法

    1 xff1a 打开 html 文件 在linux 命令行 输入firefox help 显示信息 查看某个html 文件 xff0c 举例如下 xff0c 输入命令后 大概需要等3秒 xff0c firefox进程启动 xff0c 浏览器
  • ROS 与 MATLAB通信

    ros 与 matlab 通讯使用的是ros中的主从机策略 1 准备条件 1 首先我们需要在matlab上安装 Robotics System Toolbox 工具箱 xff0c matlab2015B及以后自动安装有这个工具箱 xff0c
  • radmin

    正向连接 xff1a 由控制端发起连接 xff08 RADMIN xff09 反向链接 xff1a 由被控端发起连接 xff08 鸽子 xff09 radmin视频教程 xff1a http video sina com cn v b 68
  • Python利用GPU加速代码进行深度学习

    对于初次使用GPU加速代码的学习者来说 xff0c 需要在电脑上安装支持GPU加速的部件 xff0c 分以下三个步骤 xff1a 安装支持GPU版本的Pytorch xff08 非cpu版本 xff09 安装GPU版本的pytorch 在如
  • 6.4学习记录

    因为最近在看的一本书叫 高质量前入式LinuxC编程 xff0c 所以大部分内容是直接借鉴的 以下为6 4的学习记录 1 数据类型这一章中 xff0c 变量和常量的区分 局部变量和全局变量的区分 2 基本内置类型 有整形 xff0c 实型
  • docker常用命令

    Docker https www docker com 是一个不断发展的系统 xff0c 开发人员主动致力于提高使用率和性能 所以命令总是在变化 Docker命令经常被弃用并替换为新的或更有效的命令 你可以使用help选项检查Docker安
  • 函数指针的好处、作用

    C中函数指针的作用 项目中用到了很多封装在struct中的函数指针 xff0c 以前在MFC里面经常用到则个作为回调函数 xff0c 还以为是微软设计的特色呢 在网上查了一下它的用法 xff0c 做个总结 1 xff09 提供调用的灵活性