c++ 函数指针_进化论——从函数指针到被结构封装的函数指针及参数的应用举例...

     ↑↑↑ 点击上方公众号名称关注,不放过任何转变的机会。

d65ef758f8fac8a43a7227e7d18cdd9e.png

✎ 编 者 悟 语

        借口再小也会瓦解人的意志。

文 章 导 读

    今天带大家用下函数指针,然后将函数指针和函数参数封装到结构体中,接着将数据用动态分配和静态分配的方式赋值给相应的函数,从而实现比较灵活的函数封装和调用的目的。

1函数指针
#include #include // 图省事,函数定义在main函数前了int TestFun1(int val1, int val2){    return (val1 + val2); }int TestFun2(int val1, int val2){    return (val1 - val2); }// 定义函数指针fun指向 int(*)(int,int)类型的函数int (*fun)(int val1, int val2); int main(int argc,char *argv[]){    // 指向要操作的函数,并赋值参数    fun = TestFun1;    printf("testFun1 = %d\n",(*fun)(2,1));    fun = TestFun2;    printf("testFun2 = %d\n",(*fun)(2,1));    }

    运行结果:

      53f73be124a5b87887b160e40ab82ba7.png

关于int (*fun)(int,int)需要说明下,其为定义一个函数指针fun,它指向返回值为int,两个参数类型都是int的函数。即fun指向的函数类型为 int(*)(int,int),也可以说fun是int(*)(int,int)型的指针。2结构封装函数指针及参数

    1)动态分配方式调用

#include #include // 指针fun指向 int (*)(int , int )的函数typedef int (*fun)(int val1, int val2);   // 定义封装的函数及参数typedef struct{    int val1;    int val2;    fun function;  }TestStruct_t;int TestFun1(int val1, int val2){    return (val1 + val2);  }int TestFun2(int val1, int val2){    TestStruct_t t;      // 调用函数TestFun1,与TestFun2参数交叉使用,实际中根据需要来    t.function = TestFun1;    t.val1 = val1 + 1;    t.val2 = (*(t.function))(t.val1, val2); // t.val1 + val2 = val1 + 1 + val2      return (t.val2 - t.val1);               // t.val2 - t.val1 = (val1 + 1 + val2) - (val1 + 1) = val2}// 定义testStruct_t类型的二维数组,动态分配时没用TestStruct_t testArray[2][3] ={    {3,      2,     TestFun1},      {4,      5,     TestFun2}      };int main(int argc,char *argv[]){    // 动态分配空间    TestStruct_t *pMap = malloc(sizeof(testStruct_t));        // 给动态分配的空间赋值    pMap->val1 = 4;    pMap->val2 = 6;    // TestFun2 处理结构是获得参数val2的值,只是为了演示没有啥实际意义    pMap->function = TestFun2;         // 指定参数获得指向函数的返回值      printf("%d",(*(pMap->function))(pMap->val1, pMap->val2));  }

    运行结果:

      c4bd98a6b8593f37b1a349a25ad97f00.png

TestFun2利用封装的结构体类型引入TestFun1函数,利用结构体分装方便切换函数。

    2)静态分配方式调用

#include #include // fun 指向 int (*)(int , int )typedef int (*fun)(int val1, int val2);   // 定义封装的函数及参数typedef struct{    int val1;    int val2;    fun function;  }TestStruct_t;int TestFun1(int val1, int val2){    return (val1 + val2);  }int TestFun2(int val1, int val2){    TestStruct_t t;      // 调用函数TestFun1,与TestFun2参数交叉使用,实际中根据需要来    t.function = TestFun1;    t.val1 = val1 + 1;    t.val2 = (*(t.function))(t.val1, val2); // t.val1 + val2 = val1 + 1 + val2      return (t.val2 - t.val1);               // t.val2 - t.val1 = (val1 + 1 + val2) - (val1 + 1) = val2}TestStruct_t testArray[2][3] ={    {3,      2,      TestFun1},      {4,      5,      TestFun2}      };int main(int argc,char *argv[]){      TestStruct_t *pMap; //利用数组的静态空间即可,不用动态分配了 //  testStruct_t *pMap = malloc(sizeof(testStruct_t));         pMap = testArray[1]; //将数组第二行的首地址赋给testStruct_t类型的指针pMap// 用数组中的值赋值,不用下面的赋值了    /*    pMap->val1 = 4;    pMap->val2 = 6;    pMap->function = TestFun2;*/                printf("\nThe value of TestFun2 is:%d\n",(*(pMap->function))(pMap->val1, pMap->val2));  }

    运行结果:

      ec21c302b0d983382b2f3e1809177c3f.png

可以看出,在此实例中动态分配与静态分配主要差别在内存分配方式和赋值形式上。

总结

    总的来说,不封装的函数指针调用函数还是比较清晰的,但做比较大的项目的时候有时需要灵活的将函数及参数封装起来,一是方便管理,二是运用灵活。

推荐文章:

宏分类的妙用(排版开始用模板)

用Dev-C++生成dll动态链接库文件并用C代码调用
指定常量、变量、函数在存储空间的地址
功能多样的预处理指令#pragma

printf与#和##的魔幻组合

扫码关注我们

8a49007e85e8bee5241c37e06331d105.png

7a43d55f743eb4b1073f21e08efcdb39.gifGame Over!

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

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

相关文章

python怎么做软件界面_python – 如何自定义桌面应用程序的标题栏和窗口

我如何自定义标题栏(包括:关闭,最大化,最小化按钮,标题)和用PyQt编写的桌面应用程序框架,使其看起来像下面的图像?我需要一种方法来指定我想用于标题栏元素的颜色(按钮,文本标题和条形和按钮的背景颜色).我需要更改其窗口的代码: import sys …

python绘制社会关系网络图_Python networkx 网络图绘制

简单演示import networkx as nx import matplotlib.pyplot as plt # 定义空图 g nx.Graph() # 增加节点 g.add_node(1) g.add_node(A) g.add_nodes_from([2, 3]) g.add_edge(2, 3) g.add_edges_from([(1, 2), (1, 3)]) nx.draw(g, with_labelsTrue) plt.show() 一次增加多个点…

查看LINUX放开端口,linux如何查看端口是否开放?

在linux中我们可以通过在命令行中使用lsof命令、netstat命令来检查端口是否开放。方法一:使用lsof命令我们可以使用lsof命令来检查某一端口是否开放,基本语法如下:lsof -i:端口号如果没有任何输出则说明没有开启该端口号下图以80端口和53端口…

python数据处理框架_python 最快 web 框架 Sanci 快速入门

简介 Sanic 是一个和类Flask 的基于Python3.5的web框架,它编写的代码速度特别快。 除了像Flask 以外,Sanic 还支持以异步请求的方式处理请求。这意味着你可以使用新的 async/await 语法,编写非阻塞的快速的代码。 关于 asyncio 包的介绍&…

linux tcp ip c,Linux下TCP/IP编程--TCP实战(select)

本文参考自徐晓鑫《后台开发》,记录之。一、为什么要使用非阻塞I/O之select初学socket的人可能不爱用select写程序,而习惯诸如connect、accept、recv/recvfrom这样的阻塞程序。当让服务器同时为多个客户端提供一问一答服务时,很多程序员采用多…

单片机8×8点阵显示简单汉字的程序_干货 | 浅析单片机制作贪吃蛇游戏

为了让大家更深入地了解底层的原理,在讲解时特意选择了51单片机(而非STM系列),另外16*16点阵由译码器和移位缓存器直接驱动(而非MAX系列芯片),摇杆也利用ADC功能判断方向。那如何让单片机驱动这256个点呢?直接用IO口驱动显然不够且…

怎样在linux中创建硬盘,在linux中添加新硬盘并创建LVM组

1、以虚拟机为例,给虚拟机添加一块新硬盘,并创建LVM组,将新硬盘用于存放oracle数据库文件。2、fdisk -ll查看新添加的硬盘是否被识别,如图已经识别出sdb。3、# pvcreate /dev/sdb (创建PV,相当于win中将基础磁盘转换…

双代号网络图基础算法_软考网络工程师之系统开发和运行基础(软件分类、测试、模型)...

系统开发和运行基础(软件的分类、软件生存周期、软件开发模型、软件测试、软件项目管理)软件的分类系统软件,如操作系统。支撑软件,如开发工具。应用软件,如office。实时处理软件,一般是工业软件。软件生存周期1、软件定义问题定义…

在学Python前学Linux,Python原来这么好学-1.2节: 在Linux中安装python

这里将告诉您Python原来这么好学-1.2节: 在Linux中安装python,具体操作过程:在Linux系统的主要发行版中,按其软件包格式来进行划分,可分为Deb系以及RPM系操作系统。Linux系统与Windows系统有一个很重要的区别,Linux系统完全免费,开…

python金融大数据分析视频_Python金融大数据分析 PDF 全书超清版

给大家带来的一篇关于Python相关的电子书资源,介绍了关于Python金融、大数据分析方面的内容,本书是由人民邮电出版社出版,格式为PDF,资源大小47.8 MB,希尔皮斯科编写,目前豆瓣、亚马逊、当当、京东等电子书…

kaggle房价预测特征意思_机器学习-kaggle泰坦尼克生存预测(一)-数据清洗与特征构建...

1、背景:1.1 关于kaggle:谷歌旗下的 Kaggle 是一个数据建模和数据分析竞赛平台。该平台是当下最流行的数据科研赛事平台,其组织的赛事受到全球数据科学爱好者追捧。 如果学生能够在该平台的一些比赛中获得较好的名次,不仅可以赢得…

linux docker安装svn,使用docker镜像搭建svn+Apache环境

环境准备虚拟机装好之后,按照官网步骤检查虚拟机内核版本,必须在3.10以上版本,故此处安装redhat_7.2# uname -r3.10.0-327.el7.x86_64安装docker:yum install docker-io有依赖是直接安装具体的依赖软件,解决依赖docker…

springboot 设置ico_Spring Boot--Thymeleaf模板引擎/静态页面

点关注,不迷路;持续更新Java相关技术及资讯!!!1.Spring Boot对静态资源的映射规则如果静态资源文件夹下有 index.html的话,直接访问localhost:8080的话,index就是欢迎页使用自己的图标:在静态资源文件夹放一个 favicon…

linux shell 豆瓣,用Linux shell脚本爬取豆瓣邮箱

前两天总结一下邮箱格式的正则表达式,写了一个脚本来判断输入的邮箱地址是否符合邮箱的格式(有兴趣的朋友可以翻一下我的博客去看一下)。在网上找资料的时候,发现基本都是用Python和Java来做爬虫,当然Python的居多。本着学习的心态&#xff0…

php 获取header_php 输出404状态码

今天在做一个php数据提交的小功能时,需要在判断一个值是如果为空时,就让后台的逻辑页面返回 404 状态码,提示用户页面不存在。那么接下来,飞鸟慕鱼博客要说的是 php 如何返回或输出 html 404 的状态码。php header()函数header()&…

getcwd和pwd为什么不一样_农村医保,为什么每个地区收费不一样?

新农村合作医疗保险的缴费标准,为什么每个地区都不一样呢?我们可能不难发现,就是说你在的地区每年交费可能是280元,但是别的人在的地区可能交费达到了306元或者说320元,这究竟是一种什么样的情况呢?其实每个…

矩阵论思维导图_《实变函数论》 江泽坚 3rd 思维导图与笔记整理

实变函数学十遍实变函数应该是你们本科所有数学课程中最难的了 ————韦老师如是说学期初就知道这个课不好学。话不多说,期末之前把复习导图全部做完了,po上来分享。注:由于制作辛苦,所以预先告知收取些许费用(不到一…

jackson 读取多文件_Spring Boot系列之读取配置

使用SpringBoot框架开发,读取配置是少不了的,那么你会读取配置吗?你会写配置吗?List?Map?1 目的本节我们要解决如下几个问题:如何使用Spring Boot读取配置文件?有哪些方式&#xff1…

ab plc编程软件_AB编程软件及所有组态软件授权及安装教程包含FTViewV11

前面发了几个求助的帖子,希望有朋友能提供些Factory Talk View V11的安装和授权,但是一直没有什么回复,今天结合别人的经验,算是把授权安装搞定了,在这里发布出来,希望能帮助到更多的朋友,授权和…

c++ udp多线程 例子_[内附完整源码和文档] 基于udp实现tcp功能进行大文件传输

一.项目要求Please choose one of following programing languages: C, C, Java, Python;本项目采用的是python3.6LFTP should use a client-server service model;本项目使用客户端-服务器的模式LFTP must include a client side program and a server side program; Client s…