结构体中定义函数指针
结构体指针变量的定义,定义结构体变量的一般形式如下:
形式1:先定义结构体类型,再定义变量
struct结构体标识符
{
成员变量列表;…
};
struct 结构体标识符 *指针变量名;
变量初始化一:struct结构体标识符 变量名={初始化值1,初始化值2,…, 初始化值n };
形式2:在定义类型的同时定义变量
struct结构体标识符
{
成员变量列表;…
} *指针变量名;
变量初始化二:
形式3:直接定义变量,用无名结构体直接定义变量只能一次
struct
{
成员变量列表;…
}*指针变量名;
其中“指针变量名”为结构体指针变量的名称。形式1是先定义结构体,然后再定义此类型的结构体指针变量;形式2和形式3是在定义结构体的同时定义此类型的结构体指针变量。
函数指针的定义
一般的函数指针可以这么定义:
int(*func)(int,int);
表示一个指向含有两个int参数并且返回值是int形式的任何一个函数指针. 假如存在这样的一个函数:
int add2(int x,int y)
{
return x+y;
}
那么在实际使用指针func时可以这样实现:
func=&add2; //指针赋值,或者func=add2; add2与&add2意义相同
printf("func(3,4)=%d\n",func(3,4));
事实上,为了代码的移植考虑,一般使用typedef定义函数指针类型.
typedef int(*FUN)(int,int);
FUN func=&add2;
func();
结构体中包含函数指针
其实在结构体中,也可以像一般变量一样,包含函数指针变量.下面是一种简单的实现.
#include <stdio.h>
struct DEMO
{
int x,y;
int (*func)(int,int); //函数指针
};int add1(int x,int y)
{
return x*y;
}int add2(int x,int y)
{
return x+y;
}void main()
{
struct DEMO demo;
demo.func=add2; //结构体函数指针赋值
//demo.func=&add2; //结构体函数指针赋值
printf("func(3,4)=%d\n",demo.func(3,4));
demo.func=add1;
printf("func(3,4)=%d\n",demo.func(3,4));
}/*
输出:
func(3,4)=7
func(3,4)=12
*/结构体中指向函数的指针
C语言中的struct是最接近类的概念,但是在C语言的struct中只有成员,不能有函数,但是可以有指向函数的指针,这也就方便了我们使用函数了。举个例子,如下:#include <stdio.h>
#include <stdlib.h>
#include <string.h>typedef struct student
{int id;char name[50]; void (*initial)();void (*process)(int id, char *name);void (*destroy)();
}stu;void initial()
{printf("initialization...\n");
}void process(int id, char *name)
{printf("process...\n%d\t%s\n",id, name);
}void destroy()
{printf("destroy...\n");
}int main()
{stu *stu1;//在VC和TC下都需要malloc也可以正常运行,但是linux gcc下就会出错,为段错误,必须mallocstu1=(stu *)malloc(sizeof(stu));//使用的时候必须要先初始化stu1->id=1000;strcpy(stu1->name,"C++");stu1->initial=initial;stu1->process=process;stu1->destroy=destroy;printf("%d\t%s\n",stu1->id,stu1->name);stu1->initial();stu1->process(stu1->id, stu1->name);stu1->destroy();free(stu1);return 0;
}
输出:
/*
1000 C++
initialization...
process...
1000 C++
destroy...
*/
c语言中,如何在结构体中实现函数的功能?把结构体做成和类相似,让他的内部有属性,也有方法
这样的结构体一般称为协议类,提供参考:
struct {
int funcid;
char *funcname;
int (*funcint)(); /* 函数指针 int 类型*/
void (*funcvoid)(); /* 函数指针 void类型*/
};
每次都需要初始化,比较麻烦
#include <stdio.h>typedef struct
{
int a;
void (*pshow)(int);
}TMP;void func(TMP *tmp)
{if(tmp->a >10)//如果a>10,则执行回调函数。{(tmp->pshow)(tmp->a);}
}void show(int a)
{printf("a的值是%d\n",a);
}void main()
{TMP test;test.a = 11;test.pshow = show;func(&test);
}/*
一般回调函数的用法为:
甲方进行结构体的定义(成员中包括回调函数的指针)乙方定义结构体变量,并向甲方注册,
甲方收集N个乙方的注册形成结构体链表,在某个特定时刻遍历链表,进行回调。
当 函数指针 做为函数的参数,传递给一个被调用函数,
被调用函数就可以通过这个指针调用外部的函数,这就形成了回调一般的程序中回调函数作用不是非常明显,可以不使用这种形式
最主要的用途就是当函数不处在同一个文件当中,比如动态库,要调用其他程序中的函数就只有采用回调的形式
通过函数指针参数将外部函数地址传入来实现调用
函数的代码作了修改,也不必改动库的代码,就可以正常实现调用便于程序的维护和升级
*/
参考:
C结构体中的函数指针与函数
函数指针模拟多态
相关文章:

对卫星网络及内容的安全防护措施
对卫星网络及内容的安全防护措施 网络安全是多领域的综合业务,近10年来在规模和范围方面都获得了极大的发展。对网络及内容潜在的威胁来自各类不同的领域,因此增加了解决这一问题的难度。 在因特网产生之前,对卫星网络及内容实时***的安全防护…
对标Pytorch,清华团队推出自研AI框架“计图”
「AI技术生态论」 人物访谈栏目是CSDN发起的百万人学AI倡议下的重要组成部分。通过对AI生态专家、创业者、行业KOL的访谈,反映其对于行业的思考、未来趋势的判断、技术的实践,以及成长的经历。2020年,CSDN将对1000人物进行系列访谈࿰…

echo使用说明,参数详解
简介 echo [OPTION]... [STRING]... 描述 -n 末尾不加换行 -e 开启输出字串中对反斜杠的转译 -E 禁用反斜杠转译 只有开启-e参数的时候,下面的命令才能起作用: \0NNN 输出NNN(一个八进制数)在ASCII码表中对应的字符, …
ATSS : 目标检测的自适应正负anchor选择,很扎实的trick | CVPR 2020
作者 | VincentLee来源 | 晓飞的算法工程笔记论文地址:https://arxiv.org/abs/1912.02424代码地址:https://github.com/sfzhang15/ATSS在仔细比对了anchor-based和anchor-free目标检测方法后,结合实验结果,论文认为两者的性能差异…

GCC编译选项--创建与使用库
系统函数库使用 linux系统函数库位于/usr/lib和/lib目录下 #include <math.h> #cc test.c -lm -o test 动态库创建 1).编译时指定-fPIC 通知gcc产生可以重定位的与位置无关的目标代码 2).链接时指定-shared 使gcc编译器生成动态链接库 动态库使用 通过设置环境…

不错的×××实验
(virtual private network 虚拟专网),利用公用网络,按照相同的策略和规则,建立内部私有连接。 广泛的讲,***体系结构分为:站点到站点的***和远程访问*** 站点到站点的***:在这种情况下,同一个机…
达观数据于敬:个性化推荐系统实践
达观数据于敬:个性化推荐系统实践 在DT(data technology)时代,网上购物、观看视频、聆听音乐、阅读新闻等各个领域无不充斥着各种推荐,个性化推荐已经完全融入人们的日常生活当中。个性化推荐根据用户的历史行为数据进行深层兴趣点挖掘&#…

C语言Free时报错HEAP CORRUPTION DETECTED
char *k1; k1 (char *) malloc(4*sizeof(char)); v1 (char *) malloc(4*sizeof(char)); strcpy(k1,"abcd"); free(k1); 在linux下不会报错,但是在VC环境会报错:HEAP CORRUPTION DETECTED 出现这个错误的原因一般都是操作new申请的内存溢…

DivCSS网页布局中CSS无效的十个常见原因
在学习DivCSS网页布局的知识,可是W3C validation有时难以操作,但用它你可以查看由版面设计引起的差错。验证程序抛出大量差错和警告,说明你的XHTML尚未完善,可能无法在不同浏览器上保持一致功能。下面十个细微的失效问题难住了大批…
如何创建计算机视觉场景训练数据
作者 | 刘明宽 数据科学部门负责人,澳鹏(Appen)美国 曾任eBay首席研究科学家(数据科学总监)对于一些精度要求不太高,或者不太复杂的计算机视觉应用场景,利用一些现有的开源数据集如ImageNet/Coc…

express中的bin/www文件详解
2019独角兽企业重金招聘Python工程师标准>>> #!/usr/bin/env node 表明是node执行文件,在做repl工具时候的会用的 "#!"是标识符/usr/bin是环境变量的绝对路径/env 如果是直接#!/usr/bin node ,则执行这个文件的时候,会从/usr/bin中找node命令,如果没有,则…
深度分析typedef--定义自己的数据类型
最近在看redis源码的时候看到Ae.h的时候看到如下源码: /* Types and data structures */ typedef void aeFileProc(struct aeEventLoop *eventLoop, int fd, void *clientData, int mask); typedef int aeTimeProc(struct aeEventLoop *eventLoop, long long id, void *client…
Go对Python产生的冲击
作者 | yuliao来源 | 懒编程(ID: hackpython)Go 的流行让以 Python 为主流语言的开发者(比如我)产生了一定的危机感。上一次有这种危机感还是做 Android 开发的时候,当时用 Java 做 Android 开发,Google 强…

更新ADT到Android L的方法
android ADT无法更新到20? 哈哈,有办法,windows 进入host 写入例如以下所有,是的所有。然后在到sdk manager中方可更新 #Google Services START #Googleapis↓ 61.19.1.54 mt0.googleapis.com 61.19.1.54 mt1.googleapis.com 61…

php.ini安全配置详细解释
PHP本身再老版本有一些问题,比如在 php4.3.10和php5.0.3以前有一些比较严重的bug,所以推荐使用新版。另外,目前闹的轰轰烈烈的SQL Injection也是在PHP上有很多利用方式,所以要保证 安全,PHP代码编写是一方面&am…
5 亿微博数据疑泄露,Python 爬虫如何避免踩天坑?
作者 | 马超来源 | CSDN(ID:CSDNnews)3月19日,默安科技CTO魏兴国发微博称,微博数据泄露了不少用户的手机号,当中涉及不少微博认证的明星和企业家。亦有网友在他的微博评论区表示:“有超过5.38亿…
GDB使用总结
经典编译参数: # cc -g -o xx xx.c 或者 # cc xx.c -g -o xx 如果调试不是进程总的程序 可以直接 #gdb 程序名即可 # i 打印行号 #break 行号 #r 重新开始调试 利用set args 命令就可以修改发送给程序的参数,而使用show args 命令…

Spring概述
Spring 是什么Spring是一个开源的轻量级Java SE(Java 标准版本号)/Java EE(Java 企业版本号)开发应用框架,其目的是用于简化企业级应用程序开发。应用程序是由一组相互协作的对象组成。而在传统应用程序开发中…
Nginx模块开发
最简单的Nginx模块开发,虽然简单,但是是最重要的第一步。 主要是看:http://blog.codinglabs.org/articles/intro-of-nginx-module-development.html 1.准备模块文件 在nginx-1.4.2安装目录新建一个自己的模块的目录 # mkdir myModule 再新…
程序猿惯用口头禅与内心真实 OS,快来看看你中招没?
作者 | 他二哥来源 | 腾讯技术工程滑动查看真实内心 OS滑动查看真实内心 OS滑动查看真实内心 OS滑动查看真实内心 OS滑动查看真实内心 OS滑动查看真实内心 OS滑动查看真实内心 OS滑动查看真实内心 OS滑动查看真实内心 OS【end】◆精彩推荐◆推荐阅读百万人学AI:CSDN…

每日学习笔记(1)
1,python2.4不支持下面这种异常处理语法 try: except: finally: 只有2.5以上才行,为此只能改成下述写法,damn fuck python 2.4... try: try: except: finally: 2,python实现单例模式的一种方法: class MyCl…

linux svn使用方法
1 安装 svn sudo apt-get install subversion 2 查看svn版本号 svn version 3 下载源代码 下面以举例 svn co svn://192.168.5.88/ erppurchase -username hming -password hming /var/www/test 4更新代码 cd /var/www/test/ svn up 当前目录下所有的文件都更新 svn up -r 200…
64% 的企业未实现智能化,5成公司算法工程师团队规模小于 10人,AI 工程师的机遇在哪里?...
整理 | 夕颜责编 | 唐小引出品 | CSDN(ID:CSDNnews)当前,人工智能技术已应用于各行各业,落地成为大家关注的核心问题。在经历了 2019 年的行业低谷期之后,无论是行业巨头还是新兴独角兽,都开始审视 AI 能够…
指针的本质--u_char*指针在Nginx源码中的应用及原因
GNU下的void *p相当于char *p 也就是移动一个字节。 下面的代码是Nginx中内存池的结构体代码,其中last和end是表示内存地址的。 last是u_char*指针类型也就是unsigned char typedef struct {u_char *last;u_char *end;ngx_pool_t …

原来这就是乡下人
来源:http://user.qzone.qq.com/313998514/blog/1215427152#!app2&viaQZ.HashRefresh&poscatalog_private 今天早晨一早就去做家教了, 原因是我的学生要去香港去学习七天, 明天就要走了, 所以为了赶时间, 今天的课就提到早晨来上. 这些都很正常, 早晨6:17我…

如何查看Apache的连接数和当前连接数
查看Apache的连接数和当前的连接数以及IP访问次数,下面有个不错的示例,大家可以参考下,希望对大家解决问题有所帮助查看了连接数和当前的连接数 复制代码 代码如下:netstat -ant | grep $ip:80 | wc -l netstat -ant | grep $ip:80 | grep ES…
linux环境insight安装与使用
去官网下载:ftp://sourceware.org/pub/insight/releases 安装步骤 # wget ftp://sourceware.org/pub/insight/releases/insight-6.8-1a.tar.bz2 # tar xvf insight-6.8-1a.tar.bz2 # cd ./ # ./configure --prefix/usr/local/insight # make 注意第一次make…

磁盘加密软件TrueCrypt知识大全(二)之创建文件型加密卷
磁盘加密软件TrueCrypt知识大全(二)之创建文件型加密卷 1、在“TrueCrypt”窗口中选择“创建加密卷(C)”按钮,在向导中选择“创建文件型加密卷”,然后一直下一步。 2、在TrueCrypt加密卷创建向导中单击“选…
你的企业在什么情况下需要人工智能?快来看看你需要具备哪些条件与能力吧!...
作者 | Anzhela Sychyk译者 | 风车云马 责编 | 徐威龙出品 | AI科技大本营(ID:rgznai100)如今有关人工智能的炒作多得令人眼花缭乱。各个行业都极力采用这种技术,以获得相对于其他企业的竞争优势——降低运营成本,并改善客户体验。…

struts2学习笔记--线程安全问题小结
在说struts2的线程安全之前,先说一下,什么是线程安全?这是一个网友讲的, 如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的&#x…