C语言结构体中定义函数指针详解

2023-11-14

原文链接:https://blog.csdn.net/qq_21792169/article/details/50436089

结构体指针函数应用场景之一–驱动程序编写

struct i2c_driver {
	int (*probe)(struct i2c_client *, const struct i2c_device_id *); //probe函数
	struct device_driver driver; //表明这是一个驱动
	const struct i2c_device_id *id_table; //要匹配的从设备信息(名称)
	int (*detect)(struct i2c_client *, struct i2c_board_info *); //设备探测函数
	const unsigned short *address_list; //设备地址
	struct list_head clients; //设备链表
};

struct bus_type i2c_bus_type = {
	.name		= "i2c",
	.match		= i2c_device_match,
	.probe		= i2c_device_probe,
	.remove		= i2c_device_remove,
	.shutdown	= i2c_device_shutdown,
	.pm		= &i2c_device_pm_ops,
};

在学习嵌入式我们经常和结构体函数指针打交道,还有链表,环形缓冲区之类的,这里中点讲解结构体中定义函数指针。下面这个程序你看一遍你基本也明白用法了。

下面是我写的一个很简单的程序struct.c

#include <stdio.h>  /* 标准输入输出头文件 */
#include <stdlib.h> /* strtoul用到的头文件 */


struct test_pfun                                          { /* 定义一个结构体,里面有三个成员,是三个函数指针 ,前面千万不要加static,这里并没有分配内存*/
int (*add) (int a,int b);
int (*sub) (int a,int b);
int (*mult) (int a,int b);
};

static int  test_add(int a,int b)   /* 定义求和函数 */
{
   return (a+b);
}

static int  test_sub(int a,int b)   /* 定义相减函数 */
{
   return (a-b);
}

static int   test_mult(int a,int b)   /* 定义乘法函数 */
{
   return (a*b);
}


struct test_pfun pfun={    /* 关键的地方时在这里,看怎么函数指针赋值 */
 .add   =test_add,
 .sub   =test_sub,
 .mult  =test_mult,
};

/*
*  usage:
*  ./a.out num1 num2 
*/
void print_uage()
{
   printf("./a.out <num1> <num2>\n ");    /* 打印用法 */
}

int main(int argc,char **argv)
{
   int a ,b;  
   if(argc!=3)
   {
 print_uage();
return -1;
   }
  a=strtoul(argv[1],NULL,0);    /* 把字符串argv[1]转换成一个整数a */
  b=strtoul(argv[2],NULL,0);   /* 把字符串argv[2]转换成一个整数b */



/* 不懂strtoul命令的请点击这里:点击这里! */

printf("a+b=%d\n",pfun.add(a,b));
printf("a-b=%d\n",pfun.sub(a,b));
printf("a*b=%d\n",pfun.mult(a,b));
   return 0;
}

结构体的一些基本用法

形式1:先定义结构体类型,再定义变量

struct结构体标识符
{
成员变量列表;…
};
struct 结构体标识符 *指针变量名;

变量初始化一:struct结构体标识符 变量名={初始化值1,初始化值2,…, 初始化值n };

形式2:在定义类型的同时定义变量

struct结构体标识符
{
成员变量列表;…
} *指针变量名;

形式3:直接定义变量,用无名结构体直接定义变量只能一次

struct
{
成员变量列表;…
}*指针变量名;

其中“指针变量名”为结构体指针变量的名称。形式1是先定义结构体,然后再定义此类型的结构体指针变量;形式2和形式3是在定义结构体的同时定义此类型的结构体指针变量

结构体指针在嵌入式Linux驱动中的典型应用

最后我在举一个驱动中的典型例子:

struct button_irq_desc {   /* 定义一个结构体,只是定义这种类型。再次强调前面不要加上static ,现在还没有分配内存 */
    int irq;
    unsigned long flags;
    char *name;
};

/* 用来指定按键所用的外部中断引脚及中断触发方式, 名字 */
static struct button_irq_desc button_irqs [] = {    /* 定义一个button_irq_desc结构体类型名字button_irqs的4元数组,这里就可以加上上static ,你定义变量当然得分配内存空间 */
    {IRQ_EINT19, IRQF_TRIGGER_FALLING, "KEY1"}, /* K1 */
    {IRQ_EINT11, IRQF_TRIGGER_FALLING, "KEY2"}, /* K2 */
    {IRQ_EINT2,  IRQF_TRIGGER_FALLING, "KEY3"}, /* K3 */
    {IRQ_EINT0,  IRQF_TRIGGER_FALLING, "KEY4"}, /* K4 */
};


request_irq(IRQ_EINT0,  buttons_irq, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, "S2", &pins_desc[0]);

struct pin_desc * pindesc = (struct pin_desc *)dev_id;    /* 强制转换成struct pin_desc *指针,这儿是驱动程序的用法 ,看不懂没有关系*/

这里我们还可以定义结构体指针对数组操作:

static struct button_irq_desc p_irq_desc=button_irqs; / 结构体数组的首地址 */

使用数组中其他选项时候,只需让p_irq_desc这个地址加一,这里加一等于地址加上sizeof(p_irq_desc)。

linux设备驱动之I2C

https://herok.blog.csdn.net/article/details/49048549

Linux I2C驱动框架(超详细)

https://blog.csdn.net/weixin_42462202/article/details/91128914?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7Edefault-1.queryctr&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7Edefault-1.queryctr&utm_relevant_index=2

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

C语言结构体中定义函数指针详解 的相关文章

  • 归档文件系统或格式

    我正在寻找一种文件类型来存储已退役系统的档案 目前 我们主要使用 tar gz 但从 200GB tar gz 存档中查找并提取几个文件是很麻烦的 因为 tar gz 不支持任何类型的随机访问读取规定 在你明白之前 使用 FUSE 安装 t
  • 并行运行 make 时出错

    考虑以下制作 all a b a echo a exit 1 b echo b start sleep 1 echo b end 当运行它时make j2我收到以下输出 echo a echo b start a exit 1 b star
  • QFileDialog::getSaveFileName 和默认的 selectedFilter

    我有 getSaveFileName 和一些过滤器 我希望当用户打开 保存 对话框时选择其中之一 Qt 文档说明如下 可以通过将 selectedFilter 设置为所需的值来选择默认过滤器 我尝试以下变体 QString selFilte
  • 何时使用 pthread 条件变量?

    线程问题 看来 只有在其他线程调用 pthread cond notify 之前调用 pthread cond wait 时 条件变量才起作用 如果在等待之前发生通知 那么等待将被卡住 我的问题是 什么时候应该使用条件变量 调度程序可以抢占
  • 创建 jar 文件 - 保留文件权限

    我想知道如何创建一个保留其内容的文件权限的 jar 文件 我将源代码和可执行文件打包在一个 jar 文件中 该文件将在使用前提取 人们应该能够通过运行批处理 shell 脚本文件立即运行示例和演示 然后他们应该能够修改源代码并重新编译所有内
  • Android:ANT 构建失败,并显示 google-play-services-lib:“解析为没有项目的 project.properties 文件的路径”

    我正在尝试使用 ANT 构建我的应用程序 但在包含 google play services lib 库项目后 我惨遭失败 Step 1 我在 project properties 文件中设置了对库项目的引用 android library
  • 强制卸载 NFS 安装目录 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案
  • 跟踪 Linux 程序中活跃使用的内存

    我想跟踪各种程序在特定状态下接触了多少内存 例如 假设我有一个图形程序 最小化时 它可能会使用更少的内存 因为它不会重新绘制窗口 这需要读取图像和字体并执行大量库函数 这些对象仍然可以在内存中访问 但实际上并没有被使用 类似的工具top它们
  • 如何使用 bash 锁定文件

    我有一个任务从远程服务器同步目录 rsync av email protected cdn cgi l email protection srv data srv data 为了使其定期运行并避免脚本 reEnter 问题 我使用 rsyn
  • 如何在 Linux 中编写文本模式 GUI? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 当我编写脚本 程序时 我经常想弹出一个简单的文本 gui 来提示输入 我该怎么做 例如 来自 Shel
  • 如何禁用 GNOME 桌面屏幕锁定? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何阻止 GNOME 桌面在几分钟空闲时间后锁定屏幕 我已经尝试过官方手册了在红帽 https access redhat com doc
  • Jenkins中找不到环境变量

    我想在詹金斯中设置很多变量 我试过把它们放进去 bashrc bash profile and profile of the jenkins用户 但 Jenkins 在构建发生时找不到它们 唯一有效的方法是将所有环境变量放入Jenkinsf
  • 如何查明CONFIG_FANOTIFY_ACCESS_PERMISSIONS是否启用?

    我想利用fanotify 7 http man7 org linux man pages man7 fanotify 7 html我遇到的问题是在某些内核上CONFIG FANOTIFY ACCESS PERMISSIONS不起作用 虽然C
  • Linux中的CONFIG_OF是什么?

    我看到它在很多地方被广泛使用 但不明白在什么场景下我需要使用它 What is 配置 OF OF 的全名是什么 打开固件 这是很久以前发明的 当时苹果公司正在生产基于 PowerPC CPU 的笔记本电脑 而 Sun Microsystem
  • sendfile64 只复制约2GB

    我需要使用 sendfile64 复制大约 16GB 的文件 到目前为止我所取得的成就是 include
  • fopen 不返回

    我在 C 程序中使用 fopen 以只读模式 r 打开文件 但就我而言 我观察到 fopen 调用没有返回 它不返回 NULL 或有效指针 执行在 fopen 调用时被阻止 文件补丁绝对正确 我已经验证过 并且不存在与权限相关的问题 任何人
  • Linux 中的动态环境变量?

    Linux 中是否可以通过某种方式拥有动态环境变量 我有一个网络服务器 网站遵循以下布局 site qa production 我想要一个环境变量 例如 APPLICATION ENV 当我在 qa 目录中时设置为 qa 当我在生产目录中时
  • Android 时钟滴答数 [赫兹]

    关于 proc pid stat 中应用程序的总 CPU 使用率 https stackoverflow com questions 16726779 total cpu usage of an application from proc
  • 如何有效截断文件头?

    大家都知道truncate file size 函数 通过截断文件尾部将文件大小更改为给定大小 但是如何做同样的事情 只截断文件的尾部和头部呢 通常 您必须重写整个文件 最简单的方法是跳过前几个字节 将其他所有内容复制到临时文件中 并在完成
  • 添加要在给定命令中运行的 .env 变量

    我有一个 env 文件 其中包含如下变量 HELLO world SOMETHING nothing 前几天我发现了这个很棒的脚本 它将这些变量放入当前会话中 所以当我运行这样的东西时 cat env grep v xargs node t

随机推荐

  • 数据库技术之mysql50题

    目录 数据表介绍 数据SQL 练习题 数据表介绍 1 学 表 Student SId Sname Sage Ssex SId 学 编号 Sname 学 姓名 Sage 出 年 Ssex 学 性别 2 课程表 Course CId Cname
  • 18-Go语言之单元测试

    go test工具 Go语言中的测试依赖go test命令 编写测试代码和编写普通的Go代码过程是类似的 并不需要学习新的语法或工具 go test命令是一个按照一定约定和组织的测试代码的驱动程序 在包目录内 所有以 test go为后缀的
  • 就业DAY7_web服务器_http协议

    import socket def servece client new socket 为这个客户端返回数据 1 接收浏览器发送过来的请求 即http请求 GET HTTP 1 1 request new socket recv 1024
  • 【Unity3D】如何快速做出点击按钮切换场景

    1 首先建立第一个场景 在Canvas创建一个Button 快捷键为Ctrl N 再按Ctrl S保存该场景到文件 如图所示 图中的 开始 为按钮 2 创建第二个场景 作为点击按钮后切换的场景 点击左上角 File Build Settin
  • 精心挑选了三种热门的Python技术书籍送给大家!!

    本周三狗哥给大家挑选了三种热门的Python书籍 送给大家 每种书送两本 共6本 文末查看送书规则 Python大数据分析 公众号回复 送书 Python最优化算法实战 扫码回复 送书 Python数据分析 扫码回复 送书 公众号回复 送书
  • js 把带有对象的数组里的某个属性组成新的数组

    如果想将数组对象中的某个属性组成一个新的数组 可以使用Array map 方法 这个方法会遍历原始数组的每个元素 并返回一个新的数组 其中包含指定属性的值 以下是一个示例 假设有一个包含对象的数组 每个对象都有一个name属性 你想要将所有
  • html5新特性

    目录 使用语义化标签的目的 1 html5新增的语义化标签 2 html新增的多媒体标签 1 视频 video 2 音频 audio 属性 object fit 3 html5新增的input表单元素属性 1 新增的input标签type属
  • 准备加入第二个项目(第5960小时加入)

    今天 老师过来办事 看了我做的东西后 邀请我加入他的项目 让我受宠若惊 2012年10月 我加入老师的项目后 2天内落荒而逃 因为一句代码都没有写出来 再然后 老师以我没有项目经验为由 拒绝了我后来想加入项目的要求 2年后 老师邀请我去做项
  • 安装Anaconda科学计算包

    Anaconda介绍 最近在看 Python语言及其应用 这本书 作为一本介绍Python语言和应用的书非常不错 在这本书的最后 介绍了一些Python常用的第三方类库 像科学计算库 金融计算库 图形图像库等等 其中也介绍了Anaconda
  • 移动端H5页面生成图片解决方案

    现在有很多微信公众号运营活动 都有生成图片的需求 生成图片后可以发送给好友和发到朋友圈扩散 利于产品的宣传 1 生成图片可以用canvas 但是由于已经有了html2canvas这个开源库 所以为了节省时间就没有自己写了 github地址
  • 为什么文件删除了但磁盘空间没有释放?

    1 案例现象 这天 监控系统发来一条告警消息 内容说某台服务器根目录磁盘占用空间达到阈值 超过百分之八十了 登上服务器 df Th 看一下 发现磁盘空间确实不够用了 root localhost df Th 文件系统 类型 容量 已用 可用
  • java怎么从一个类传值到另一个类,关于JAVA的引用类型传值.

    方法参数传递都按值传递 对于基本类型 传递原始值 对于对象类型 传递其指向的对象的地址值 多个同类型不同的变量可以指向同一个对象 但是其中任何一个变量被重新赋值 也就是指向一个新的对象时 不影响其它变量的指向 方法定义的形参 在调用的发生的
  • Socket编程之聊天程序 - 模拟Fins/ModBus协议通信过程

    设备控制软件编程涉及到的基本通信方式主要有TCP IP与串口 用到的数据通信协议有Fins与ModBus 更高级别的通信如 net中的Remoting与WCF在进行C S架构软件开发时会采用 本篇文章结合Fins ModBus协议的指令帧结
  • 关于前端获取后端传输的参数并在js中应用该参数

    在进行dynamicTree名称获取时 如果是涉及到不同数据库需要使用不同的dynamicTree的xml文件且该名称在前端写死状态 可以采用setAttribute方法将值赋给前端 前端用 接收该值 并在js处使用document get
  • TCP UDP协议的应用以及高级IO的介绍

    TCP UDP协议的应用以及高级IO的介绍 网络通信协议 模型 TCP和UDP两个协议都是一对多的网络通信模型 TCP编程模型 UDP编程模型 实例 TCP模型 聊天室的服务器 有私密消息功能以及列出聊天者的功能 include
  • RCE远程命令执行漏洞挖掘思路

    RCE漏洞可能出现在哪些地方 1 URL上 在url参数上 不仅仅可能存在ssrf漏洞 也有很大概率存在命令执行 很大可能调用系统命令如curl payload例子 index php id 2 phpinfo ttp www xxx co
  • ue4编辑模型时,让模型底部刚好在地面上的方法

    选中模型按住End键
  • Matlab 公式大全

    1 MATLAB公式 例如 在命令窗口中输入sin pi 5 然后单击回车键 则会得到该表达式的值 sin pi 5 ans 0 5878 例如 sin 1 9 pi sin 2 9 pi sin 3 9 pi sin 4 9 pi sin
  • linux软件共用的依赖关系,利用 yum 解决 Linux 软件包的依赖关系

    在Linux系统软件安装包依赖关系是一个很烦恼的问题 yum能够从指定的服务器自动下载RPM包并且安装 可以自动处理依赖性关系 并且一次安装所有依赖的软体包 无须繁琐地一次次下载 安装 可以利用ftp和Createrepo共同搭建本地软件库
  • C语言结构体中定义函数指针详解

    C语言结构体中定义函数指针详解 结构体指针函数应用场景之一 驱动程序编写 结构体的一些基本用法 形式 先定义结构体类型 再定义变量 形式 在定义类型的同时定义变量 形式 直接定义变量 用无名结构体直接定义变量只能一次 结构体指针在嵌入式Li