第36课 函数与指针分析

1. 函数类型

(1)C语言中的函数有自己特定的类型,这个类型由返回值、参数类型参数个数共同决定。如int add(int i,int j)的类型为int(int,int)。

(2)C语言中通过typedef为函数类型重命名

typedef type name(parameter list);//如typedef int f(int,int);

2. 函数指针

(1)函数指针用于指向一个函数,函数名是执行函数体的入口地址

(2)定义函数指针的两种方法

①通过函数类型定义:FuncType* pointer;

②直接定义:type(*pointer)(parameter list);

//其中type为返回值类型,pointer为函数指针变量名,parameter list为参数类型列表

【实例分析】函数指针的使用(技巧:使用函数指针直接跳转到某个固定的地址开始执行)

#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; //合法,函数名就是函数体的入口地址

    //直接定义函数指针,&f是旧式写法。函数名只是一个符号(不是变量),
    //与数组名一样,并不为其分配内存,因此&f和f在数值上是相等的。
    void(*pf)() = &f; //如果知道某个函数的地址,这里可以改为一个固定的地址值,实现跳转!

    printf("pf = %p\n",pf);
    printf("f = %p\n",f);
    printf("&f = %p\n",&f); //结果应为:pf == f == &f;

    pf();//利用函数指针调用

    (*pf)(); //旧式写法

    printf("Function pointer call:%d\n",pt(2));

    return 0;
}

3. 回调函数

(1)回调函数是利用函数指针实现的一种调用机制

(2)回调机制原理

  ①调用者不知道具体事件发生时需要调用的具体函数

  ②被调函数不知道何时被调用,只知道需要完成的任务

  ③当具体事件发生时,调用者通过函数指针调用具体函数

(3)回调机制中的调用者和被调用者互不依赖

【实例分析】回调函数使用示例

#include <stdio.h>

typedef int (*Weapon)(int); //操作某种武器的函数

//使用某种武器与boss进行战斗
void fight(Weapon wp,int arg) //arg为传给函数指针的参数
{
    int result = 0;

    printf("Fight boss!\n");

    result = wp(arg);//调用回调函数,并传入参数arg

    printf("Boss loss:%d\n",result);//Boss失血多少?
}

//使用武器——刀
int knife(int n)
{
    int ret = 0;
    int i = 0;

    for (i=0; i< n; i++)
    {
        printf("Knife attack:%d\n",1);
        ret++;
    }

    printf("\n");

    return ret;
}

//使用武器——剑
int sword(int n)
{
    int ret = 0;
    int i = 0;

    for (i=0; i< n; i++)
    {
        printf("Sword attack:%d\n",5);
        ret++;
    }

    printf("\n");

    return ret;
}

//使用武器——枪
int gun(int n)
{
    int ret = 0;
    int i = 0;

    for (i=0; i< n; i++)
    {
        printf("Gun attack:%d\n",10);
        ret++;
    }

    printf("\n");

    return ret;
}

int main()
{

    fight(knife, 3);//用刀砍3次
    fight(sword, 4);//用剑刺4次
    fight(gun, 5);  //开枪5次

    return 0;
}

4. 小结

(1)C语言中的函数都有特定的类型

(2)可以使用函数类型定义函数指针

(3)函数指针是实现回调机制的关键技术

(4)通过函数指针可以在C程序中实现固定地址跳转

时间: 2024-10-21 14:24:36

第36课 函数与指针分析的相关文章

C语言-第36课 - 函数递归与函数设计技巧

第36课 - 函数递归与函数设计技巧 一. 递归 递归概述 (1) 递归是数学领域中的概念在程序设计中的应用. (2) 递归是一种强有力的程序设计的方法. (3) 递归的本质为函数内部在适当的时候调用自身. 组成部分 (1)递归点:以不同参数调用自身. (2)出口:不在递归调用 下面就是求一个数的阶乘的函数: #include <stdio.h> int func(int x) { if( x > 1 ) { return x * func(x - 1);  //递归点 } else {

第46课 函数与宏分析

1. 函数与宏 (1)宏是由预处理直接替换展开的,编译器不知道宏的存在 (2)函数是由编译器直接编译的实体,调用行为由编译器决定 (3)多次使用宏会导致最终可执行程序的体积增大 (4)函数是跳转执行的,内存中只有一份函数体存在 (5)宏的效率比函数要高,因为是直接展开,无调用开销 (6)函数调用时会创建活动记录,效率不如宏 [编程实验]函数与宏 #include <stdio.h> #define RESET(p,len) while( len > 0) ((char*)p)[--len

第5课 C语言指针深入1

1.客户端两种主流的接口模型: #ifndef _SOCKETCLINET_H #endif _SOCKETCLINET_H #ifdef __cplusplus //如果用了C++的编译器,用C语言的规范来引用 extern "C" { #endif //socket客户端环境初始化 int socketclient_init(void** handle); //socket客户端报文发送 int socketclient_send(void* handle, unsigned ch

【C语言探索之旅】 第二部分第二课:进击的指针,C语言的王牌!

内容简介 1.课程大纲 2.第二部分第二课: 进击的指针,C语言的王牌 3.第二部分第三课预告: 数组 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写三个游戏. C语言编程基础知识 什么是编程? 工欲善其事,必先利其器 你的第一个程序 变量的世界 运算那点事 条件表达式 循环语句 实战:第一个C语言小游戏 函数 练习题 习作:完善第一个C语言小游戏 C语言高级技术 模块化编程 进击的指针,C语言王牌 数组 字符串 预处理 创建你自己的变量类型

20150430 调试分析之 根据内核报错信息PC指针分析错误

20150430 调试分析之 根据内核报错信息PC指针分析错误 2015-04-30 Lover雪儿 大家写驱动的时候不知道有没有发现,当我们驱动写错了,发生内核奔溃时,会打印一大堆的报错信息, 如果再返回我们的程序中一行一行代码的检查,既耗费时间,并且有些逻辑上的错误,我们是很难看的出来的, 那我们能不能再这一大堆的报错信息中发现问题的所在呢? 此处我们来模拟一个错误,还是沿用上一篇文章中的驱动代码err_led.c的驱动程序中的代码修改错误,当然大家用其他的驱动代码做测试也可以. 博客地址:

【C++】函数和指针

最近在看C++ primer plus,感觉函数与指针这一章难点比较多,记写笔记,加强理解. From C++ Primer Plus: Chapter 7 Function:C++ Programming Modules 1. 如何声明函数指针? 和函数原型类似: 需要声明指针指向函数的返回值和参数列表 double pam(int); //参数为int 类型,返回值为double 类型的函数 double (*pf);(int) //指向参数为int类型,返回值为double 类型的指针 p

类成员函数的指针与多态性

1 类成员函数的指针 2 类成员函数的指针数组 3 指向类成员函数的指针的指针 1 类成员函数的指针 auto func1 = &com::jia;//C++函数指针 int (com::*p)(int, int) = &com::jia;//C函数指针 1 #include <iostream> 2 3 class com 4 { 5 private: 6 int a; 7 int b; 8 public: 9 com(int x, int y) :a(x), b(y) 10

iOS指向函数的指针和block

  一:block基础知识 block基础知识 基本概念:block是用来保存一段代码的:^:是block得标志  好比*:是指针的标志 特点:1:保存一段代码: 2:可以有参数和返回值: 3:可以作为函数的参数传递: 与代码块的区别,代码块里的代码会自动执行,block中代码要手动调用: 二:普通数据类型.指向函数的指针.block的定义的类比 1:基本数据类型: 例如:int a = 10; 格式:数据类型  变量名 = 值: 2:指向函数的指针:可以仿照上边基本数据类型的定义 例如:voi

指向类成员函数的指针

//类中的普通成员变量,类名::变量名,在栈上 //类名 *指针名=new 类名,在堆上 //类的静态成员变量,在静态区 //函数都在代码区,类的函数.静态函数都是共享的 void(myclass::*p1)() = myclass::run;//指向类成员函数的指针 void(*p2)() = myclass::go;//指向静态成员函数的指针 1 #include <iostream> 2 3 class myclass 4 { 5 public: 6 int num; 7 int dat