【C】 36_函数与指针分析
函数类型
- 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_函数与指针分析相关推荐
- c语言回调函数_C语言学习第26篇---函数与指针分析 回调函数
函数类型的概念 1.C语言函数也是有类型的 2.函数类型由函数返回值,参数类型,参数个数共同决定 int add(int i,int j) 的类型是 int(int , int) 3.C语言中通过ty ...
- Point-to Analysis指针分析(2)
上一篇文章是Point-to Analysis指针分析(1) 下面介绍一种新的指针分析的算法Steensgaard算法,并将其与上一篇文章介绍的Andersen算法相比较. Steensgaard算法 ...
- 【c++】5.函数传指针与传值特容易混淆的点
函数传指针与传值特容易混淆的点 这里只做一部分的解析,详解请参考 指针参数传递动态内存 https://blog.csdn.net/daaikuaichuan/article/details/7722 ...
- 函数、指针、数组的组合 及结构体和共用体
1.数组与函数 1) 数组元素作参数 large(int x, int y){...}; large(a[2], a[3]); 1) 数组名作参数 计算数组中用户6个月的积分平均值 float ave ...
- python asyncio回调函数_python回调函数用法实例分析
python回调函数用法实例分析 本文实例讲述了python回调函数用法.分享给大家供大家参考.具体分析如下: 软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用.回调和异步 ...
- 指向函数的指针 - C语言
欢迎访问我的新博客:http://www.milkcu.com/blog/ 原文地址:http://www.milkcu.com/blog/archives/1368947400.html 基本概念 ...
- C函数调用过程原理及函数栈帧分析
在x86的计算机系统中,内存空间中的栈主要用于保存函数的参数,返回值,返回地址,本地变量等.一切的函数调用都要将不同的数据.地址压入或者弹出栈.因此,为了更好地理解函数的调用,我们需要先来看看栈是怎么 ...
- 【软件分析/静态程序分析学习笔记】7.指针分析(Pointer Analysis)入门
写在前面的话 本渣有幸成为南京大学软件学院研究生,在前往仙林校区蹭课的时候偶然发现了这门宝藏课程,听了以后感觉深有收获,但又因为课程难度较大,国庆假期归来发现遗忘较多,因此开了一坑来记录自己对每节课知 ...
- c语言指针与函数ppt,函数与指针C语言.ppt
函数与指针C语言.ppt 函数与指针 第7章 7 1概述 第7章 1 按功能划分模块划分模块的基本原则是 各模块都要易于理解 功能尽量单一 模块间的联系尽量少 满足这些要求的模块具有以下优点 7 1 ...
最新文章
- 实现简书个人中心UI效果
- 【Linux 内核】实时调度类 ⑥ ( 实时调度类核心函数源码分析 | 插入进程到执行队列 | 从执行队列中选择优先级最高的进程 )
- 未能找到类型或命名空间名称_命名空间详解
- 《数学之美》——第三章 个人笔记
- 高德地图api接口文档_在 R 语言里面调用高德地图接口:地理编码与路径规划
- mybatis学习(1):【持久化框架】Mybatis简介与原理
- 向量叉乘判断两向量之间是顺时针还是逆时针
- Skywalking-03:Skywalking本地调试
- 为什么从事软件开发测试?
- Intellij IDEA 安装插件 报 ‘plugin xxxx is incompatible‘ 解决方案
- Navicat 中文破解版
- 帆软客户画像分析与客户价值模型
- mysql数据库管理-sql_mode参数(严格和非严格模式)
- CentOS7安装DockerCentOS7安装DockerCompose
- C#最小二乘法进行曲线拟合及相关系数
- 文件操作SaveFileDialog的用法
- python怎么加油_使用 Python 为你的油箱加油
- Mac下录制屏幕视频
- Toast(提示信息),Dialog(弹窗).
- 永久の思い出 --- 玉玲 命中の美しいMELODY