函数类型

  • C 语言中的函数都有自己特定的类型
  • 函数的类型由返回值参数类型参数个数共同决定
    int add(int i, int j) 的类型为 int(int, int)
  • C 语言中通过 typedef 为函数类型重命名
    typedef type name(parameter list)

typedef int f(int, int);
typedef void p(int);

函数指针

  • 函数指针用于指向一个函数
  • 函数名是执行函数体的入口地址
  • 可以通过函数类型定义函数指针: FuncType* pointer;
  • 也可以直接定义: type (*pointer)(parameter list);

    • pointer 为函数指针变量名
    • type 为所指函数的返回值类型
    • parameter list 为所指函数的参数类型列表

面试小问题

  • 如何使用 C 语言直接跳转到某个固定的地址开始执行?

通过函数指针完成,使用固定的地址初始化函数函数指针。多用于嵌入式设备开发中。

实例分析: 函数指针的使用

Test_1.c

#include <stdio.h>typedef int(FUNC)(int);int test(int i)
{return i * i;
}void f()
{printf("Call f()...\n");
}int main()
{FUNC* pt = test;void (*pf)() = f;printf("pf = %p\n", pf);printf("f = %p\n", f);printf("&f = %p\n", &f);pf();(*pf)(); printf("Fucntion pointer call: %d\n", pt(2));return 0;
}
输出:
pf = 0x8048400
f = 0x8048400
&f = 0x8048400
Call f()...
Call f()...
Fucntion pointer call: 4分析:
f    <==> pf
pf() <==> (*pf)()

Test_2.c

#include <stdio.h>typedef int(FUNC)(int);int test(int i)
{return i * i;
}void f()
{printf("Call f()...\n");
}int main()
{FUNC* pt = test;void (*pf)() = (void(*)())(0x8048400);   // pf 由一个固定的内存地址初始化!!printf("pf = %p\n", pf);printf("f = %p\n", f);printf("&f = %p\n", &f);pf();(*pf)();printf("Fucntion pointer call: %d\n", pt(2));return 0;
}
输出:
pf = 0x8048400
f = 0x8048400
&f = 0x8048400
Call f()...       【跳转到一个固定的地址,成功执行】
Call f()...       【跳转到一个固定的地址,成功执行】
Fucntion pointer call: 4

回调函数

  • 回调函数是利用函数指针实现的一种调用机制
  • 回调机制原理

    • 调用者不知道具体事件发生时需要调用的具体函数
    • 被调函数不知道何时被调用,只知道需要完成任务
    • 当具体事件发生时,调用者通过函数指针调用具体函数
  • 回调机制中的调用者和被调用者互不依赖

实例分析: 回调函数使用示例

#include <stdio.h>typedef int(*Weapon)(int);void fight(Weapon wp, int arg)
{int result = 0;printf("Fight boss!\n");result = wp(arg);printf("Boss loss: %d\n", result);
}int knife(int n)
{int ret = 0;int i = 0;for(i=0; i<n; i++){printf("Knife attack: %d\n", 1);ret ++;}return ret;
}int sword(int n)
{int ret = 0;int i = 0;for(i=0; i<n; i++){printf("Sword attack: %d\n", 10);ret ++;}return ret;
}int gun(int n)
{int ret = 0;int i = 0;for(i=0; i<n; i++){printf("Gun attack: %d\n", 5);ret ++;}return ret;
}int main()
{fight(knife, 3);fight(sword, 4);fight(gun, 5);return 0;
}
输出:
Fight boss!
Knife attack: 1
Knife attack: 1
Knife attack: 1
Boss loss: 3
Fight boss!
Sword attack: 5
Sword attack: 5
Sword attack: 5
Sword attack: 5
Boss loss: 4
Fight boss!
Gun attack: 5
Gun attack: 5
Gun attack: 5
Gun attack: 5
Gun attack: 5
Boss loss: 5

小结

  • C 语言中的函数都有特定的类型
  • 可以使用函数类型定义函数指针
  • 函数指针是实现回调机制的关键技术
  • 通过函数指针可以在 C 程序中实现固定地址跳转

以上内容参考狄泰软件学院系列课程,请大家保护原创!

【C】 36_函数与指针分析相关推荐

  1. c语言回调函数_C语言学习第26篇---函数与指针分析 回调函数

    函数类型的概念 1.C语言函数也是有类型的 2.函数类型由函数返回值,参数类型,参数个数共同决定 int add(int i,int j) 的类型是 int(int , int) 3.C语言中通过ty ...

  2. Point-to Analysis指针分析(2)

    上一篇文章是Point-to Analysis指针分析(1) 下面介绍一种新的指针分析的算法Steensgaard算法,并将其与上一篇文章介绍的Andersen算法相比较. Steensgaard算法 ...

  3. 【c++】5.函数传指针与传值特容易混淆的点

    函数传指针与传值特容易混淆的点 这里只做一部分的解析,详解请参考 指针参数传递动态内存 https://blog.csdn.net/daaikuaichuan/article/details/7722 ...

  4. 函数、指针、数组的组合 及结构体和共用体

    1.数组与函数 1) 数组元素作参数 large(int x, int y){...}; large(a[2], a[3]); 1) 数组名作参数 计算数组中用户6个月的积分平均值 float ave ...

  5. python asyncio回调函数_python回调函数用法实例分析

    python回调函数用法实例分析 本文实例讲述了python回调函数用法.分享给大家供大家参考.具体分析如下: 软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用.回调和异步 ...

  6. 指向函数的指针 - C语言

    欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/1368947400.html 基本概念 ...

  7. C函数调用过程原理及函数栈帧分析

    在x86的计算机系统中,内存空间中的栈主要用于保存函数的参数,返回值,返回地址,本地变量等.一切的函数调用都要将不同的数据.地址压入或者弹出栈.因此,为了更好地理解函数的调用,我们需要先来看看栈是怎么 ...

  8. 【软件分析/静态程序分析学习笔记】7.指针分析(Pointer Analysis)入门

    写在前面的话 本渣有幸成为南京大学软件学院研究生,在前往仙林校区蹭课的时候偶然发现了这门宝藏课程,听了以后感觉深有收获,但又因为课程难度较大,国庆假期归来发现遗忘较多,因此开了一坑来记录自己对每节课知 ...

  9. c语言指针与函数ppt,函数与指针C语言.ppt

    函数与指针C语言.ppt 函数与指针 第7章 7 1概述 第7章 1 按功能划分模块划分模块的基本原则是 各模块都要易于理解 功能尽量单一 模块间的联系尽量少 满足这些要求的模块具有以下优点 7 1 ...

最新文章

  1. 实现简书个人中心UI效果
  2. 【Linux 内核】实时调度类 ⑥ ( 实时调度类核心函数源码分析 | 插入进程到执行队列 | 从执行队列中选择优先级最高的进程 )
  3. 未能找到类型或命名空间名称_命名空间详解
  4. 《数学之美》——第三章 个人笔记
  5. 高德地图api接口文档_在 R 语言里面调用高德地图接口:地理编码与路径规划
  6. mybatis学习(1):【持久化框架】Mybatis简介与原理
  7. 向量叉乘判断两向量之间是顺时针还是逆时针
  8. Skywalking-03:Skywalking本地调试
  9. 为什么从事软件开发测试?
  10. Intellij IDEA 安装插件 报 ‘plugin xxxx is incompatible‘ 解决方案
  11. Navicat 中文破解版
  12. 帆软客户画像分析与客户价值模型
  13. mysql数据库管理-sql_mode参数(严格和非严格模式)
  14. CentOS7安装DockerCentOS7安装DockerCompose
  15. C#最小二乘法进行曲线拟合及相关系数
  16. 文件操作SaveFileDialog的用法
  17. python怎么加油_使用 Python 为你的油箱加油
  18. Mac下录制屏幕视频
  19. Toast(提示信息),Dialog(弹窗).
  20. 永久の思い出 --- 玉玲 命中の美しいMELODY

热门文章

  1. 张亚勤院士谈“智能计算新趋势”
  2. AI解梦成为现实,贝尔实验室新算法尝试找到梦境的隐藏含义
  3. 数字孪生:连结现实与数字世界
  4. 5G 标准的走向,为何越来越不同寻常?
  5. 日韩决裂,半导体谁最受伤?
  6. 英国前首相:为什么欧洲没有诞生互联网巨头?
  7. 苹果着手自研调制解调器,以应对高通天价专利费
  8. 神经尘埃、脑波打字…… 2018年的脑科学要研究什么?
  9. 漫画:崩溃了!!这程序是什么玩意儿!!!
  10. 技术大牛成长记,4年成就开源社区创始人