【C语言】深入理解函数指针

函数指针是 C 语言中一个非常有用且强大的概念,它允许我们将函数作为参数传递给其他函数、在运行时动态选择要调用的函数以及实现回调函数等功能。在本篇博客中,我们将深入探讨函数指针的概念、用法以及其在实际编程中的应用。

目录

前言

什么是函数指针

函数指针的用法

示例一

示例二  转移表的实现

应用场景

结语


前言

我们都知道指针指向的是地址,那么函数是否具有地址呢,只有当函数具有地址的时候才可以被指针指向。于是我们用一下代码做一个实验:

#include<stdio.h>int Add(int x, int y)
{return x + y;
}int main()
{printf("%p", &Add);return 0;
}

通过以上代码运行得到Add函数的地址为:004413CA

以上可以说明函数是有地址的,指针可以指向函数,所以可以使用函数指针。


什么是函数指针

函数指针是指向函数的指针变量。在 C 语言中,函数名实际上是一个指向函数代码的指针,因此我们可以将函数名赋值给一个函数指针变量,从而通过函数指针来调用函数。函数指针的声明形式为 return_type (*pointer_name)(parameter_list);,其中 return_type 是函数返回类型,pointer_name 是函数指针变量的名称,parameter_list 是函数的参数列表。

声明形式详细解剖:

int (*pf3) (int x, int y)
|     |           |
|     |           |
|     |           pf3指向函数的参数类型和个数的交代
|     函数指针变量名
pf3指向函数的返回类型int (*) (int x, int y) //pf3函数指针变量的类型
//声明时可以写成int (*) (int , int),将x和y省略

函数指针的用法

示例一

下面是一个简单的代码示例:

#include <stdio.h>void say_hello() 
{printf("Hello, World!\n");
}void say_goodbye() 
{printf("Goodbye, World!\n");
}int main() 
{void (*function_ptr)();function_ptr = say_hello;function_ptr();function_ptr = say_goodbye;function_ptr();return 0;
}

在这个示例中,我们定义了两个函数 say_hello 和 say_goodbye,然后声明了一个函数指针 function_ptr,将 say_hello 和 say_goodbye 的地址分别赋给 function_ptr,最后通过函数指针调用这两个函数。

如果需要打印的话在使用函数指针的时候可以不解引用,例如:

#include <stdio.h>
int Add(int x, int y)
{
return x+y;
}
int main()
{
int(*pf3)(int, int) = Add;
printf("%d\n", (*pf3)(2, 3));
printf("%d\n", pf3(3, 5));
return 0;
}

运行结果:

5

8

示例二  转移表的实现

可以通过函数指针使转移表的实现变得更加简洁,用更少的代码实现多个分支不同函数的操作,可以点击下方链接阅读博主的这篇详细讲解函数指针在转移表中的运用的文章》(欢迎阅读!)

俺是链接,点俺


应用场景

函数指针在实际编程中有很多应用场景,例如在实现回调函数(在上方转移表的实现中有应用)、动态库加载、事件处理等方面都有广泛的应用。通过函数指针,我们可以实现更灵活、更高效的编程方式,提高代码的可维护性和扩展性。


结语

允许我们将函数作为参数传递、动态选择要调用的函数以及实现回调函数等功能。通过深入理解函数指针的概念和用法,我们可以更好地利用这一特性来优化程序设计和实现。希望本篇博客能帮助你更深入地理解函数指针,并在实际编程中灵活运用。如果你有任何关于函数指针或其他编程相关的问题,欢迎留言交流。感谢阅读!

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

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

相关文章

C++ 动态规划 状态压缩DP 蒙德里安的梦想

求把 NM 的棋盘分割成若干个 12 的长方形&#xff0c;有多少种方案。 例如当 N2&#xff0c;M4 时&#xff0c;共有 5 种方案。当 N2&#xff0c;M3 时&#xff0c;共有 3 种方案。 如下图所示&#xff1a; 2411_1.jpg 输入格式 输入包含多组测试用例。 每组测试用例占一行…

OCR文本纠错思路

文字错误类别&#xff1a;多字 少字 形近字 当前方案 文本纠错思路 简单&#xff1a; 一、构建自定义词典&#xff0c;提高分词正确率。不在词典中&#xff0c;也不是停用词&#xff0c;分成单字的数据极有可能是错字&#xff08;少部分可能是新词&#xff09;。错字与前后的…

webapi-元素的属性设置-图片切换的案例

元素的属性设置 1.目标 ​ 掌握图片的src属性的设置 在页面使用img标签显示一张图片, 点击这个图片更换一张新的图片 2.实现思路 使用img 指定src “路径” 指定id“one”获取img标签&#xff0c; 添加onclick 点击事件在事件处理程序函数体中修改图片的src的值 3.代码实…

uniapp设置不显示顶部返回按钮

一、pages文件中&#xff0c;在相应的页面中设置 "titleNView": {"autoBackButton": false} 二、对应的页面文件设置隐藏元素 document.querySelector(.uni-page-head-hd).style.display none

【Git】三棵“树”介绍

Git是一种分布式版本控制系统&#xff0c;它使用了三树原理来管理代码的变化和版本。 三树原理包括工作区树&#xff08;Working Tree&#xff09;、暂存区树&#xff08;Staging Area/Index&#xff09;和版本库树&#xff08;Commit/HEAD&#xff09;。 工作区树&#xff08…

计算机网络实验四

实验四 VLAN划分与配置 1、实验目的 • 理解并掌握Port Vlan的配置方法 • 理解并掌握掌握跨交换机实现VLAN的配置方法 2、实验设备 &#xff08;1&#xff09;实验内容1&#xff1a;交换机端口隔离—Port Vlan的配置 以太网交换机一台笔记本电脑一台PC机两台配置电缆、网…

二重指数和估计难多了

单变量指数和估计有指数对方法&#xff08;1933年英国人E.Phillips创造&#xff09;&#xff0c;印度人B.R.Srinivasan在1960年代搞出的二重指数对理论&#xff08;发表在 Math.Ann.)&#xff0c;由于没用二变量同步的Weyl不等式&#xff0c;是很肤浅的&#xff0c;而且1988年德…

收藏:相当大赞的来自 Agilean产品团队的2篇关于重塑敏捷组织的绩效管理的文章

Agilean产品团队&#xff0c;是吴穹博士领导下最近在国内敏捷界很厉害的产品&#xff0c;今天看到两篇相当不错的说敏捷组织的上下篇文章&#xff0c;分享下&#xff0c;地址是&#xff1a;6个原则15项举措&#xff0c;重塑敏捷组织的绩效管理&#xff08;上&#xff09; 6个原…

星宸科技SSC8826Q 驾驶辅助(ADAS)行车记录仪方案

星宸科技SSC8826Q 驾驶辅助&#xff08;ADAS&#xff09;行车记录仪方案 一、方案描述 SSC8826Q是高度集成的行车记录仪、流媒体后视镜解决方案&#xff0c;主芯片为ARM Cortex A53&#xff0c;dual core&#xff0c;主频高达1.2GHz&#xff0c;集成了64-bit dual-core RISC 处…

Windows 版Oracle 数据库(安装)详细过程

首先到官网上去下载oracle64位的安装程序 第一步&#xff1a;将两个datebase文件夹解压到同一目录中。 当下载完成后,它里面是两个文件夹 win64_11gR2_database_1of2, win64_11gR2_database_2of2,我们需要把其中的一个database文件夹整合在一起(复制一个database文件夹到另一…

如何有效的向 AI 提问 ?

目录 〇、导言 一、Base LLM 与 Instruction Tuned LLM 二、如何提出有效的问题 &#xff1f; 1. 明确问题&#xff1a; 2. 简明扼要&#xff1a; 3. 避免二义性&#xff1a; 4. 避免绝对化的问题&#xff1a; 5. 利用引导词&#xff1a; 6. 检查语法和拼写&#xff1…

哈希加密Python实现

一、代码 from cryptography.fernet import Fernet import os import bcrypt# 密钥管理和对称加密相关 def save_key_to_file(key: bytes, key_path: str):with open(key_path, wb) as file:file.write(key)def load_key_from_file(key_path: str) -> bytes:if not os.path…

【芯片设计- RTL 数字逻辑设计入门 7 -- 同步复位与异步复位详细介绍】

文章目录 复位的类型和划分同步复位综合后电路优缺点 异步复位优缺点 异步复位的时序分析&#xff08;recovery time/removal time&#xff09;异步复位&#xff0c;同步释放综合后电路优缺点 转自&#xff1a;https://blog.csdn.net/qq_40281783/article/details/128969188 复…

docker部署笔记系统flatnotes

效果 安装 创建目录 mkdir -p /opt/flatnotes/data && cd /opt/flatnotes/ chmod -R 777 /opt/flatnotes/ 创建并启动容器(可以自己修改账户和密码) docker run -d \ --restart unless-stopped \ --name flatnotes \ -p "10040:8080" \ -v "/dat…

JavaEE企业级应用软件开发—Spring框架入门学习笔记(一)

一、认识框架 实际开发中&#xff0c;随着业务的发展&#xff0c;软件系统变得越来越复杂&#xff0c;如果所有的软件都从底层功能开始开发&#xff0c;那将是一个漫长而繁琐的过程。此外&#xff0c;团队协作开发时&#xff0c;由于没有统一的调用规范&#xff0c;系统会出现大…

Unity类银河恶魔城学习记录3-4 EnemyBattleState P50

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili Enemy.cs using System.Collections; using System.Collections.Generic; …

@ResponseBody

目录 概述 用途 使用案例 用 ResponseBody 设置返回值 概述 ResponseBody注解的作用是将方法返回的对象&#xff0c;通过适当的转换器(HttpMessageConverter)转换为指定的格式之后&#xff0c;写入到response对象的body区&#xff0c;通常用来返回JSON数据或者是XML数据 用…

外汇天眼:欧洲期货交易所(Eurex)推出了基于EURO STOXX 50指数股息期货的中期期权

欧洲期货交易所&#xff08;Eurex&#xff09;将于2024年2月5日推出基于EURO STOXX 50指数股息期货的中期期权&#xff0c;扩大了其股息衍生品的产品线。 目前作为场外交易产品的中期期权&#xff08;Mid-Curve Options&#xff09;现在可以在Eurex进行交易。 中期期权&#x…

使用 openpyxl 操作 Excel

由于单位有任务&#xff0c;需要按照名册制作多个工作表。手动复制和修改内容太费事了&#xff0c;所以使用python完成此项工作&#xff0c;为之后的此类工作提供一个通用脚本。 安装依赖库 pip install openpyxl lxml我们需要用到openpyxl。在官方文档中提到&#xff0c;如果…