指针简介(3)—— 指针函数与函数指针

2023-05-16

声明:

        本文是阅读周立功老师的程序设计与数据结构后所写,很多内容其实是书中的内容,所以如果您想了解更多这方面的知识,您可以阅读这本书。

 

        在前面一节我们简单介绍了指针、数组、指针数组以及数组指针。而在这一节中我们主要介绍两个概念:函数指针函数以及函数指针。

指针函数:

        说到指针函数,他的主体还是一个函数,但是他的返回值为指针类型,因此我们通常将其称为指针函数。他通常的形式为:

int* iMax(int *a, int *b);

        注意在上面的函数中对于形参我们同样使用指针的方式,这是因为只有将实参(调用函数中的变量)以地址的方式传递给调用函数的形参才可以对其进行修改或者对其地址进行操作,而如果以实参值的方式传递给形参将只是值得复制,而并不会对实参的值有所操作。而在指针函数中我们很多时候是使用传址的方式来传递实参。这是因为只有这样在返回时才可以获得主调函数中实参的操作地址。而对于传值的情况,在被调函数操作完后函数的栈空间将被清零,所以此时传递出的地址也并不一定是我们想要的地址。

        其实指针函数在我们平时的程序写作中还是比较常见的,当我们需要对形参进行操作并将操作后的形参地址返回给主调函数时通常会用到指针函数。

函数指针:

        对于函数指针我想大家可能就不那么熟悉了,但是如果你要写嵌入式驱动程序那么你将经常用到这样的函数指针,函数指针的形式如下:

int (*compare)(void *a,void *b);

        既然我们称他为函数指针,那么他更像是一个函数的指针类型,所以他是一个指向其他函数的指针,而对于指向函数的指针我们通常使用下面的方式来将一个函数传递给这个函数指针:

int compare_int(int *a, int *b)
{
    return *a - *b;
}

int compare_conv(int *a, int *b)
{
    return *b - *a;
}

compare = compare_int;
compare(&a, &b);

compare = compare_conv;
compare(&a, &b);

        我们知道在内存中一个函数的函数名所在位置为函数的首地址,所以我们使用函数指针指向这个地址之后就可以调用这个函数的代码,即对这个函数进行操作了。

回调函数:

        而对于函数指针来说最常用的一种方式就是回调函数了,回调函数的形式为:

 

        上图中紫框表示上层主调函数,而蓝框表示下层被调函数,其中黑色箭头表示调用关系,而棕色箭头表示返回关系。而在上面的函数3通常表示回调函数。

        下面我们以一个例子向大家说明:

int compare_int(int *a, int *b)
{
    return *a - *b;
}

int compare_conv(int *a, int *b)
{
    return *b - *a;
}

typedef int (*Compare)(void *a, void *b);

int compare_num(int *a, int *b, Compare compare)
{
    return compare(a, b);
}

int main(int argc,int **argv)
{
        
    int a = 4, b = 5;
    int tmp;

    tmp = compare_num(&a, &b, compare_int);
    printf("The different is %d \n",tmp);

    tmp = compare_num(&a, &b, compare_conv);
    printf("The different is %d \n",tmp);

    return 0;
}

        上面的函数就是一个通过正序和倒序比较两个数字差的例子,从上面可以看出我们即可以正着比较同样也可以反着比较。而我们使用main函数作为上层函数调用下层函数compare_num函数,同时我们又会将两种不同的比较方式传递给下层函数compare_num。通过上面这种回调我们可以动态的改变代码和方式来来实现我们编程的目的。

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

指针简介(3)—— 指针函数与函数指针 的相关文章

随机推荐

  • git push不用输入密码(方法一)-git-credentials

    install git credentials sh 命令步骤 xff1a touch git credentialsecho 34 http username password 64 localhost 34 gt gt git cred
  • 十、如何使用perf工具分析java程序

    问题 1 xff1a 使用 perf 工具时 xff0c 看到的是 16 进制地址而不是函数名 在 CentOS 系统中 xff0c 使用 perf 工具看不到函数名 xff0c 只能看到一些 16 进制格式的函数地址 只要你观察一下 pe
  • vins环境配置(一):kalibr标定工具箱安装

    相机和IMU标定 xff1a kalibr工具包 xff0c r os环境 Indigo xff0c 在jade版本中未曾编译通过 xff0c 应该是自己的方式不对 xff0c 有待继续尝试 xff09 在github中查找kalibr项目
  • msckf_vio使用记录

    使用环境 xff1a ubuntu14 04 indigo indigo版本的ros默认支持的是opencv2 4 8 xff0c 其带的库cv bridge依赖于opencv2 但是 xff0c msckf vio使用的是Ubuntu 1
  • 无人机姿态解算:四元数及其与欧拉角的转换

    无人机姿态解算 xff1a 四元数及其与欧拉角的转换 引言 xff1a 获得无人机飞行时的飞行姿态对于无人机稳定控制来说至关重要 无人机主要通过传感器数据融合来进行状态估计 xff0c 常用于无人机的传感器包括 xff1a MPU xff0
  • (纯干货)备战“金3银4”,拿下这101道面试题“10拿9稳””!

    前言 xff1a 马上就到了 金9银10的 面试季 xff0c 在这里作者给各位整理了一些大厂常用的面试题 xff0c 希望能对各位有所帮助 正文 xff1a 1 问 xff1a 你在测试中发现了一个bug xff0c 但是开发经理认为这不
  • 用Excel分析音视频同步

    声明 xff1a 这里主要介绍如何运用Excel来分析音视频是否同步 xff0c 希望可以对大家有所帮助 介绍 xff1a 学习音视频就一定要知道做音视频同步 xff0c 而现在我们来分析音视频同步的工具也是有的 xff0c 比如easyI
  • 使用VLC 在PC端搭建RTP环境

    声明 xff1a 本文是我在工作中遇到的关于环境搭建问题后的一些总结 xff0c 希望可以对你有所帮助 介绍 xff1a 搭建方法 xff1a 1 xff09 搭建 VLC 软件 xff0c 点击媒体菜单 xff0c 选择 流 选项 xff
  • 使用VLC 在PC端搭建RTSP环境

    声明 xff1a 本文是我在工作中遇到的关于环境搭建问题后的一些总结 xff0c 希望可以对你有所帮助 介绍 xff1a 搭建方法 xff1a 1 xff09 搭建 VLC 软件 xff0c 点击媒体菜单 xff0c 选择 流 选项 xff
  • 2020总结

    2020年可以说是我开始工作的第二年了 在第一年中我可以说了解了工作和组里的基本情况 xff0c 而这第二年就开始真正的加深学习了 还是以时间线一点点的慢慢讲吧 春节前我们一边工作一边准备年会 我们公司有个惯例那就是让每年最新入职的员工来主
  • 嵌入式Linux——网卡驱动(1):网卡驱动框架介绍

    声明 xff1a 文本是看完韦东山老师的视频和看了一些文章后 xff0c 所写的总结 我会尽力将自己所了解的知识写出来 xff0c 但由于自己感觉并没有学的很好 xff0c 所以文中可能有错的地方敬请指出 xff0c 谢谢 在介绍本文之前
  • ROS发布订阅的消息的种类及使用

    1 消息 std msgs 的种类 在 opt ros melodic include std msgs文件夹中查询 或参考 xff1a https www itdaan com tw b30f2309fe4b1b2d5993c8ea0cb
  • SSD1306部分命令

    命令描述 1 基础命令 1 1 为页地址模式设置列低半字节的开始地址 xff08 00h 0Fh xff09 这个命令专门为8位列地址的低半字节设置以通过页地址模式显示RAM中的数据 而每一个数据使用后列地址会自动增加 请参考表格9 1的部
  • 嵌入式Linux——IIC总线驱动(3):IIC驱动OLED外设

    简介 xff1a 本文主要介绍在jz2440开发板上驱动OLED外设 xff0c 使其显示我们在应用层输入的语句 而同时我将该文分成了两部分 xff0c 第一部分讲解i2c总线的实现 xff0c 而第二部分讲解在i2c总线实现后 xff0c
  • 嵌入式Linux——RTC驱动(1):RTC框架分析

    简介 xff1a 本文通过分层的方式介绍RTC驱动 xff0c 通过分析RTC在不同层次中所做的不同工作 xff0c 以及各个层次之间的关系来了解RTC驱动框架 本文分为两部分 xff0c 第一部分总的介绍RTC框架 xff0c 而第二部分
  • 嵌入式Linux——DMA:在内核中简单使用DMA实现内存中数据传递

    简介 xff1a 本文主要介绍在内核中简单使用DMA实现内存数据传递 由于本篇文章中没有介绍与框架相关的程序 xff0c 只是使用字符设备来操作DMA xff0c 同时也没有抽象的层次 xff0c 因此本文中代码分析部分就相对简单 但我还是
  • 嵌入式Linux——uevent机制:uevent原理分析

    简介 xff1a 本文主要介绍uevent机制是什么 xff0c 并通过代码分析使用uevent机制生成设备节点的过程 而本文将分为两部分 xff0c 第一部分我们介绍一些预备知识和uevent的原理 xff0c 而第二部分 通过代码介绍使
  • 嵌入式Linux——kmsg:分析/proc/kmsg文件以及写自己的/proc/mymsg

    简介 xff1a 本文主要分析 proc kmsg文件的形成过程以及使用cat proc kmsg查看log buf中的信息时所要经历的代码 并结合上面的分析写自己的 proc mymsg和myprintk Linux内核 xff1a li
  • 嵌入式Linux——学习经历

    简介 xff1a 本文主要介绍我学习嵌入式的经历 并结合自身的经验希望可以对大家有所帮助 视频及教材 xff1a 郭天祥相关视频及教材 xff0c 天狼星相关视频及教材 xff0c 野火迷你相关视频及教材以及韦东山100ask官网所介绍的视
  • 指针简介(3)—— 指针函数与函数指针

    声明 xff1a 本文是阅读周立功老师的程序设计与数据结构后所写 xff0c 很多内容其实是书中的内容 xff0c 所以如果您想了解更多这方面的知识 xff0c 您可以阅读这本书 在前面一节我们简单介绍了指针 数组 指针数组以及数组指针 而