【C语言进阶篇】数组指针都学过了那么函数指针你了解嘛?

news2024/11/29 21:34:27

在这里插入图片描述

🎬 鸽芷咕:个人主页

 🔥 个人专栏:《C语言初阶篇》 《C语言进阶篇》

⛺️生活的理想,就是为了理想的生活!

文章目录

  • 📋 前言
  • 💬 函数指针
    • 💭 函数名 和 &函数
    • 💭 函数指针的定义
      • 💻 函数指针pf 和 函数名的关系
  • 💻 函数指针的应用
      • 📜 代码一讲解
      • 📜 代码二讲解
  • 📝全篇总结

📋 前言

  🌈hello! 各位宝子们大家好啊,数组指针的概念我们学完了那么今天就给大家打来函数指针的讲解!
  ⛳️函数既然也有自己的地址那么,是不是也可以用指针来存储呢?答案是是的!今天就来看一下函数指针是什么,以及如何应用!
  📚本期文章收录在《C语言进阶篇》,大家有兴趣可以看看呐
  ⛺️ 欢迎铁汁们 ✔️ 点赞 👍 收藏 ⭐留言 📝!

🔥 注:vs2022 等C语言学习工具都在《学习工具专栏》。 还有各种实用调试技巧有兴趣可以去看看!

💬 函数指针

函数指针是什么其实很简单?我们依旧可以类比一下

  • 数组指针 —— 指向数组的指针
  • 函数指针 —— 指向函数的指针

💭 函数名 和 &函数

函数既然有地址那么该怎么拿到函数的地址,数组名是数组的地址,&数组可以拿到整个数组的地址!那么函数名是函数的地址嘛?

  • 其实函数名是函数的地址
  • &函数名也是函数的地址

📚 代码演示:

#include <stdio.h>
void test()
{
    printf("hehe");
}
int main()
{
    printf("%p\n", &test);
    printf("%p\n", test);
    
    return 0;
}

📑 代码结果:
在这里插入图片描述

💭 函数指针的定义

数组指针我们知道他的指针类型是 int (*)[ ] 这样接收的,那么函数指针该怎么样书写呢?假设我们的函数指针类型的

  • 那么就应该这样书写
  • int (*pf)(int, int ) = test;
  • * 表明了他是个指针,是用 pf 接收的函数地址
  • int ()(int , int ) 说明了他是一个函数
  • 第一个int是他的返回值,括号里面的是参数类型
  • 这和数组指针是不是非常类似int (*pf)[ ]= &arr;
  • * 表明了他是个指针,是用 pf 接收的数组地址
  • int [ ] 说明了他是一个数组

✅总结:

  • int (* )(int, int)是函数指针类型
  • int (*)[ ] 是数组指针类型

📚 代码演示:

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

📑 代码结果:
在这里插入图片描述

💻 函数指针pf 和 函数名的关系

大家看啊!既然我们是用 pf 接收的函数地址,而函数名本身代表的是函数地址。所以我们可不可以说 pf 等于函数名!

  • int (*pf)(int, int) = add;
  • 所以 pf == add
  • 那么我们在用指针解引用调用函数时,是不是可以直接写
  • pf(2,3) == add(2,3)我们来试一试

📚 代码演示:

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

📑 代码结果:
在这里插入图片描述

💻 函数指针的应用

阅读两段有趣的代码:

  • 这俩句代码是干嘛呢?
//代码1
(*(void (*)())0)();
//代码2
void (*signal(int , void(*)(int)))(int);

📜 代码一讲解

其实代码一 (*(void (*)())0)(); 是调用0地址处的函数,

  1. 将 0 转换为函数指针类型 void (*)()
  2. 然后进行函数调用 (*)()

🔥 注:此代码来自于《C的陷阱与缺陷》。

在这里插入图片描述

其实这里最难理解的话就是 0 这个数字,这段代码我们只能先从 0 这个数字下手。

  • 大家看 0x00ff40 我们可以理解为**16**进制的整数!
  • 当然 我们也可以理解 0x00ff40 是个地址毕竟地址也是编号嘛!是以 16 进制编写的。

这时数字 0 就好理解了,我们可以把 0 当成一个地址里面,默认他是个整形。所以那么把地址 0 强制转换为一个函数指针

  • 然后再进行解引用调用这个函数
  • (*(void (\*)())0)();

📜 代码二讲解

其实代码二void (*signal(int , void(*)(int)))(int); 可以这样理解,

  1. signal 是 一个函数声明signal(int , void(*)(int))
  2. signal 函数有 俩个参数,第一个参数的类型是int ,第二个参数的类型是 void(*)(int) 函数指针类型
  3. 该函数指针指向的函数 有一个 int 类型的参数,返回类型是 void
  4. signal 函数的返回类型也是一个 函数指针类型void (*signal(int , void(*)(int)))(int);
  5. 该函数指针 指向的函数 有一个int 类型的参数,返回类型是 void

这样看起来这段代码是不是不好理解,那么我们对指针类型重名一下就看的简洁好懂了!

#include <stdio.h>

int main()
{
    typedef void(*pf_t)(int);
    pf_t signal(int, pf_t);

    void (*signal(int, void(*)(int)))(int);
 
    return 0;
}

📝全篇总结

✅ 归纳:
好了以上就是关于函数指针是什么,如何定义和应用就全部讲解完毕啦!
  函数指针是干嘛的?
  函数指针的定义
  函数指针的应用
  函数指针实例
☁️ 把本章的内容全部掌握,铁汁们就可以熟练应用函数指针啦!快去练起来吧!
看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注

💛 💙 💜 ❤️ 💚💓 💗 💕 💞 💘 💖
拜托拜托这个真的很重要!
你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。
在这里插入图片描述

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

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

相关文章

蕨型叶分形

目录 要点 基本语句 EraseMode 习题 1 设置颜色 2 旋转蕨型叶图 3 枝干 4 塞平斯基三角形 要点 蕨型叶是通过一个点的反复变换产生的&#xff0c;假设x是一个含有两个分量的向量&#xff0c;可以用来表示平面内的一个点&#xff0c;则可以用Axb的形式对其进行变换。 基本…

衡器关于检定分度值e和实际分度值d的一点认识

在看衡器认证的文档时有两个概念很容易混淆d(actual scale interval)和e(verification scale interval)&#xff0c;国内文档上翻译为实际分度值和检定分度值。 实际分度值(d)就是称能显示的最小刻度或最小能显示的值跨度&#xff0c;可以理解为可读精度&#xff0c;例如电子秤…

[虚幻引擎] UE里面监控每帧循环里面 C++ 函数的性能, 函数耗时,函数效率,函数执行时间

在使用C开发UE引擎&#xff0c;有时候需要监控函数的执行的执行效率&#xff0c;这个时候有两种方式可以使用。 1. 执行代码耗时时间 double ThisTime 0;{SCOPE_SECONDS_COUNTER(ThisTime);// ...// 一串代码// ...}UE_LOG(LogTemp, Log, TEXT("Stats::Broadcast %.2f&qu…

【Spring Boot】Web开发 — 数据验证

Web开发 — 数据验证 对于应用系统而言&#xff0c;任何客户端传入的数据都不是绝对安全有效的&#xff0c;这就要求我们在服务端接收到数据时也对数据的有效性进行验证&#xff0c;以确保传入的数据安全正确。接下来介绍Spring Boot是如何实现数据验证的。 1.Hibernate Vali…

mysql(三)用户权限管理

目录 前言 一、概述 二、用户权限类型 三、用户赋权 四、权限删除 五、删除用户 前言 为什么要设置用户权限&#xff1f; MySQL设置用户管理权限的主要目的是为了确保数据库的安全性和数据的机密性。以下是一些原因&#xff1a; 1. 安全性&#xff1a;MySQL是一个开源的关系型…

多线程案例 | 单例模式、阻塞队列、定时器、线程池

多线程案例 1、案例一&#xff1a;线程安全的单例模式 单例模式 单例模式是设计模式的一种 什么是设计模式&#xff1f; 设计模式好比象棋中的 “棋谱”&#xff0c;红方当头炮&#xff0c;黑方马来跳&#xff0c;针对红方的一些走法&#xff0c;黑方应招的时候有一些固定的…

【C++初阶】:模板进阶

模板进阶 一.非类型模板参数二.模板的特化1.概念2.函数模板特化3.类的特化1.全特化2.偏特化 三.模板的分离编译 一.非类型模板参数 模板参数分类类型形参与非类型形参。 类型形参即&#xff1a;出现在模板参数列表中&#xff0c;跟在class或者typename之类的参数类型名称。 非类…

Play 资产分发(Play Asset Delivery)

一、前言 Google Play发布应用&#xff0c;只支持上传aab格式文件。在之前&#xff0c;Google Play对上传apk文件限制大小不超过150MB&#xff0c;对于新的aab格式文件&#xff0c;也要求生成的目标apk不超过150MB&#xff08;GooglePlay后台使用bundletool生成apk文件&#xf…

虚拟机网络桥接,详细操作步骤,本地连接虚拟机

虚拟机网络桥接 文章目录 虚拟机网络桥接一&#xff0c;首先查看主机连接网络的网关二、打开虚拟机的worksation服务三、修改主机的VMnet8的IPV4属性四、修改虚拟机的workstation的虚拟网络五、修改VMnet8的IP,网关六、把虚拟机设置为桥接模式七、修改虚拟机的静态ip和对应的网…

JAVA面试总结-Redis篇章(三)——缓存雪崩

JAVA面试总结-Redis篇章&#xff08;三&#xff09;——缓存雪崩

测试开发之系统篇 - 常用系统命令

目录 前言&#xff1a; 查看占用端口的进程 Linux Windows 杀死进程 Linux Windows 按名称查看进程 命令行管道 后台运行服务 修改文件 Linux Mac 复制目录到远程 实时查看文件内容 查看正在运行的服务 查看服务状态 重启服务 查看内存状况 查看磁盘状况 …

基于MAXENT模型的生物多样性生境模拟与保护优先区甄选、自然保护区布局优化及未来气候变化下评估及论文写作教程

详情点击链接&#xff1a;基于MAXENT模型的生物多样性生境模拟与保护优先区甄选、自然保护区布局优化及未来气候变化下评估中的应用及论文写作 一&#xff1a;生物多样性保护格局与自然保护区格局优化 1.我国生物多样性格局与分布&#xff1b; 2.我国自然保护区格局与分布&…

前端年度工作述职报告优秀

前端年度工作述职报告优秀篇1 尊敬的各位领导、各位同仁&#xff1a; 大家好!按照20__年度我公司就职人员工作评估的安排和要求&#xff0c;我认真剖析、总结了自己的工作情况&#xff0c;现将本人工作开展情况向各位领导、同仁做以汇报&#xff0c;有不妥之处&#xff0c;希…

注册外部的AudioPolicy,监听焦点变化

开始 AudioFocus分发流程 在上面分发流程分析中&#xff0c;最终是在MediaFocusControl中进行处理的&#xff0c;在requestAudioFocus​方法中可以看到在执行焦点栈逻辑时会先执行AudioPolicy相关逻辑&#xff0c; 因此我们试一试可不可以利用这一点&#xff0c;来注册外部的…

用于开漏模式和推拉模式的 4bit 双向电平转换器MS4554N/MS4554N1

MS4554N/MS4554N1 是一款双向电平转换器&#xff0c;可以应用在 混合电压的数字信号系统。其使用两个独立构架的电源供电&#xff0c; A 端供电电压范围是 1.65V 到 5.5V &#xff0c; B 端供电电压范围是 2.3V 到 5.5V 。可用在电源电压为 1.8V 、 2.5V 、 3.3V 和…

FPGA学习——按键消抖的两种实现方法

文章目录 一、按键消抖简介1.1、为什么要按键消抖 二、C4开发板原理图三、按键消抖源码3.1、方案一&#xff08;每当检测到下降沿便开始重新计数&#xff09;3.2、方案二&#xff08;检测到第一次下降沿后便开始计数&#xff09; 四、仿真代码及仿真波形图五、拓展&#xff1a;…

【金万维】使用天联高级版登录用友U8,文件输出操作。

【操作步骤】 1、通过天高客户端登录U8后&#xff0c;打开对应的报表或者列表&#xff08;以余额表为例&#xff09;。 2、点击“输出”按钮后&#xff0c;弹出“另存为”窗口&#xff0c; 注意&#xff1a;当前“保存在&#xff1a;桌面”这个路径为服务器的桌面&#xff0c;…

matlab 读取fig中的数据

1.使用命令打开fig open(文件名.fig) 2.查看图像包含的数据和属性 Location是原始的&#xff0c;Normal 可能是调整了顺序后的。

echarts制作多个纵轴的折线图

代码 <script type"text/javascript"> $(function (){var myChart echarts.init(document.getElementById(main));option {color: ["#9bbb59","#0B438B","#4141F1","#F81945","#4bacc6","#F89E19&q…

怎么把知识问答做成二维码?分享简单的二维码制作工具

现在无论是工厂的职工还是学校的学生&#xff0c;都会有各种各样的知识问答。传统的纸质知识问答&#xff0c;不仅浪费人力物力&#xff0c;还需要占用上班或是上学的时间来完成。为了方便大家使用&#xff0c;我们可以把知识问答做成二维码图片&#xff0c;随时随地手机扫一扫…