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

C语言:函数指针的使用

在C语言中,函数指针是指向函数的指针变量。它可以存储函数的地址,使得可以通过该指针来调用函数。以下是函数指针的基本概念和用法:

一、基本概念:

  1. 声明函数指针:

    returnType (*pointerName)(parameterTypes);

    这里 returnType 是函数返回类型,parameterTypes 是函数参数类型。例如:

    int (*add)(int, int); // 声明一个函数指针,指向接受两个int参数并返回int的函数。
  2. 初始化函数指针:

    add = ∑ // sum是一个函数,将其地址赋给add指针。

    或者更简洁的写法:

    add = sum; // &可以省略

二、用法示例:

#include <stdio.h>// 一个简单的函数
int sum(int a, int b) {return a + b;
}int main() {// 定义一个函数指针并初始化int (*add)(int, int) = sum;// 使用函数指针调用函数int result = add(3, 4);// 打印结果printf("Result: %d\n", result);return 0;
}

在这个例子中,add 是一个指向接受两个整数参数并返回整数的函数的指针。它被初始化为指向 sum 函数。之后,通过 add(3, 4) 调用了 sum 函数,结果被打印出来。

三、函数指针的用途:

  1. 回调函数: 允许传递函数作为参数,常用于实现回调机制,即将函数作为参数传递给另一个函数,使得在某个事件发生时调用这个函数。

    #include <stdio.h>// 回调函数
    void callbackFunction(int value) {printf("Callback: %d\n", value);
    }// 接受回调函数作为参数的函数
    void performOperation(int x, int y, void (*callback)(int)) {int result = x + y;callback(result);
    }int main() {// 使用回调函数performOperation(3, 4, callbackFunction);return 0;
    }
    

  2. 动态函数调用: 通过函数指针,可以在运行时动态地选择调用哪个函数,这样可以根据某些条件选择不同的实现。

    #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);  // 声明一个函数指针// 根据条件选择函数int condition = 1;if (condition == 1) {operation = add;} else {operation = subtract;}// 使用函数指针调用函数int result = operation(5, 3);printf("Result: %d\n", result);return 0;
    }
    
    #include<stdio.h>int add(int x,int y)
    {return x+y;} int subtract(int x,int y)
    {return x-y;
    }int multiply(int x,int y)
    {return x*y;
    }//指针做函数参数
    int prosecc(int(*p)(int,int),int a,int b)
    {int P;P = (*p)(a,b);return P;}int main(void)
    {int num;num = prosecc(add,3,4);printf("Results: %d\r\n",num);num = prosecc(subtract,4,3);printf("Results: %d\r\n",num);num = prosecc(multiply,4,3);printf("Results: %d\r\n",num);return 0;
    }
    

  3. 函数指针数组: 可以创建存储函数指针的数组,实现类似分发器的功能,根据索引或条件选择调用不同的函数。

    #include <stdio.h>int add(int a, int b) {return a + b;
    }int subtract(int a, int b) {return a - b;
    }int multiply(int a, int b) {return a * b;
    }int main() {int (*operations[])(int, int) = {add, subtract, multiply};  // 函数指针数组// 使用函数指针数组调用不同的函数int result1 = operations[0](5, 3);  // 调用addint result2 = operations[1](5, 3);  // 调用subtractint result3 = operations[2](5, 3);  // 调用multiplyprintf("Results: %d, %d, %d\n", result1, result2, result3);return 0;
    }
    

  4. 函数指针作为结构成员: 可以将函数指针作为结构的一个成员,形成函数指针结构。

    #include <stdio.h>// 定义包含函数指针的结构
    struct Operation {int (*operation)(int, int);
    };// 使用结构中的函数指针
    int performOperation(struct Operation op, int a, int b) {return op.operation(a, b);
    }// 具体的函数实现
    int add(int a, int b) {return a + b;
    }int main() {// 初始化结构并使用函数指针struct Operation addition = {add};int result = performOperation(addition, 3, 4);printf("Result: %d\n", result);return 0;
    }
    

总的来说,函数指针是C语言中强大而灵活的特性,允许在运行时动态地选择调用哪个函数,从而提高代码的灵活性和可维护性。

相关文章:

C语言:函数指针的使用

在C语言中&#xff0c;函数指针是指向函数的指针变量。它可以存储函数的地址&#xff0c;使得可以通过该指针来调用函数。以下是函数指针的基本概念和用法&#xff1a; 一、基本概念&#xff1a; 声明函数指针&#xff1a; returnType (*pointerName)(parameterTypes); 这里 r…...

「实战应用」如何用DHTMLX Gantt构建类似JIRA式的项目路线图(二)

DHTMLX Gantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表。可满足项目管理应用程序的所有需求&#xff0c;是最完善的甘特图图表库。 在web项目中使用DHTMLX Gantt时&#xff0c;开发人员经常需要满足与UI外观相关的各种需求。因此他们必须确定JavaScript甘特图库的…...

Webpack5入门到原理18:Plugin 原理

Plugin 的作用 通过插件我们可以扩展 webpack&#xff0c;加入自定义的构建行为&#xff0c;使 webpack 可以执行更广泛的任务&#xff0c;拥有更强的构建能力。 Plugin 工作原理 webpack 就像一条生产线&#xff0c;要经过一系列处理流程后才能将源文件转换成输出结果。 这条…...

PWM之舵机

舵机又称直流电机&#xff0c;如下图 本节承接上节&#xff0c;具体的PWM技术已经在上一节讲的很详细了&#xff0c;本节就不再讲了&#xff0c;那么我们的重点就放在直流电机的工作原理上了。 一、工作原理 我们研究直流电机&#xff0c;主要式研究直流电机旋转速度的调节&a…...

Python并发与多线程:IO并发(阻塞IO、非阻塞IO、IO多路复用、异步IO)

在Python中&#xff0c;有多种处理并发的方式&#xff0c;其中之一就是使用多线程进行IO并发操作。在IO操作中&#xff0c;有四种常见的方式&#xff1a;阻塞IO、非阻塞IO、IO多路复用和异步IO。 阻塞IO&#xff08;Blocking IO&#xff09;&#xff1a;当执行一个IO操作时&…...

React16源码: React中的IndeterminateComponent的源码实现

IndeterminateComponent 1 &#xff09;概述 这是一个比较特殊的component的类型&#xff0c; 就是还没有被指定类型的component在一个fibrer被创建的时候&#xff0c;它的tag可能会是 IndeterminateComponent在 packages/react-reconciler/src/ReactFiber.js 中&#xff0c;有…...

SpringBoot:详解Bean生命周期和作用域

&#x1f3e1;浩泽学编程&#xff1a;个人主页 &#x1f525; 推荐专栏&#xff1a;《深入浅出SpringBoot》《java项目分享》 《RabbitMQ》《Spring》《SpringMVC》 &#x1f6f8;学无止境&#xff0c;不骄不躁&#xff0c;知行合一 文章目录 前言一、生命周期二…...

【图解数据结构】顺序表实战指南:手把手教你详细实现(超详细解析)

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;图解数据结构、算法模板 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 一. ⛳️线性表1.1 &#x1f514;线性表的定义1.2 &#x1f514;线性表的存储结构 二. ⛳️顺序表…...

WordPress怎么禁用文章和页面古腾堡块编辑器?如何恢复经典小工具?

现在下载WordPress最新版来搭建网站&#xff0c;默认的文章和页面编辑器&#xff0c;以及小工具都是使用古腾堡编辑器&#xff08;Gutenberg块编辑器&#xff09;。虽然有很多站长说这个编辑器很好用&#xff0c;但是仍然有很多站长用不习惯&#xff0c;觉得操作太难了&#xf…...

【HarmonyOS】掌握布局组件,提升应用体验

从今天开始&#xff0c;博主将开设一门新的专栏用来讲解市面上比较热门的技术 “鸿蒙开发”&#xff0c;对于刚接触这项技术的小伙伴在学习鸿蒙开发之前&#xff0c;有必要先了解一下鸿蒙&#xff0c;从你的角度来讲&#xff0c;你认为什么是鸿蒙呢&#xff1f;它出现的意义又是…...

第4周:Pytorch——综合应用和实战项目 Day 28-30: 学习资源和社区参与

第4周&#xff1a;综合应用和实战项目 Day 28-30: 学习资源和社区参与 在这个阶段&#xff0c;我们将探索更多的学习资源并鼓励参与PyTorch和TensorFlow的社区&#xff0c;以进一步提升技术和融入开发者社群。 学习资源&#xff1a; 论文&#xff1a;阅读最新的机器学习和深度…...

TypeScript教程(一)在vscode中的配置TypeScript环境

TypeScript教程&#xff08;一&#xff09;在vscode中的配置TypeScript环境 文章目录 TypeScript教程&#xff08;一&#xff09;在vscode中的配置TypeScript环境一、前言二、具体步骤1、Node.js安装2、TypeScript安装3、helloworld 一、前言 未来的开发者们请上座&#xff0c…...

sshpass的安装与使用

一.简介 1.定义&#xff1a; ssh 登陆不能在命令行中指定密码&#xff0c;sshpass 的出现则解决了这一问题。它允许你用 -p 参数指定明文密码&#xff0c;然后直接登录远程服务器&#xff0c;它支持密码从命令行、文件、环境变量中读取。 2.使用 sshpass 原因 使用 sshpass…...

Excel·VBA合并工作簿2

其他合并工作簿的方法&#xff0c;见之前的文章《ExcelVBA合并工作簿》 目录 8&#xff0c;合并文件夹下所有工作簿中所有工作表&#xff0c;按表头汇总举例 8&#xff0c;合并文件夹下所有工作簿中所有工作表&#xff0c;按表头汇总 与之前的文章《ExcelVBA合并工作簿&#x…...

linux内核原理--分页,页表,内核线性地址空间,伙伴系统,内核不连续页框分配,内核态小块内存分配器

1.分页&#xff0c;页表 linux启动阶段&#xff0c;最初运行于实模式&#xff0c;此阶段利用段寄存器&#xff0c;段内偏移&#xff0c;计算得到物理地址直接访问物理内存。 内核启动后期会切换到保护模式&#xff0c;此阶段会开启分页机制。一旦开启分页机制后&#xff0c;内…...

【MongoDB】下载安装、指令操作

目录 1.下载安装 2.指令 2.1.基础操作指令 2.2.增加 2.3.查询 2.4.修改 2.5.删除 前言&#xff1a; 关于MongoDB的核心概念请移步&#xff1a; 【文档数据库】ES和MongoDB的对比-CSDN博客 1.下载安装 本文以安装Windows版本的mongodb为例&#xff0c;Linux版本的其实…...

k8s-pvc/pv扩容记录

背景 一次聊天过程中&#xff0c;对方提及pvc的扩容&#xff0c;虽然有注意过 storageclass 有个AllowVolumeExpansion的配置&#xff08;有些csi插件是不支持该配置的&#xff0c;比如local-volume-provisoner&#xff09;&#xff0c;但是没有实际用过&#xff0c;所以还是心…...

关于Unity插件TriLib使用的一点儿心得

最近做一个项目的时候&#xff0c;由于要求动态加载fbx或者glb等格式文件&#xff0c;而我们自己开发加载插件难度又有点大&#xff0c;所以最后使用了TriLib这个插件&#xff0c;现在说一点使用心得。 由于文件加载之后要对加载的内容进行复制&#xff0c;比如加载一个柱子&am…...

计算机二级Python基本排序题-序号45(补充)

1. 文件"singup.txt”中保存了若干条参加运动会学生的报名记录&#xff0c;每条记录的形式为“班级号_学号”&#xff0c;例如"A1_12”&#xff0c;将每个班级报名情按参加运动会人数从多到少排列&#xff08;假设不存在人数相同的情况&#xff09;并输出&#xff0c…...

响应式Web开发项目教程(HTML5+CSS3+Bootstrap)第2版 例4-6 fieldset

代码 <!doctype html> <html> <head> <meta charset"utf-8"> <title>fieldset</title> </head><body> <form action"#"><fieldset><legend>学生信息</legend>姓名&#xff1a;&…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...