首页 > 编程语言 >c++回调函数

c++回调函数

时间:2023-12-05 09:47:35浏览次数:34  
标签:const 函数 int float c++ func 回调 string

最近用到了回调函数,距离上次使用至少隔了5年了,又重新熟悉了一下。

 

 

转自:https://blog.csdn.net/hua12134/article/details/88264250

什么是函数指针
函数指针就是指向函数的指针,指向某种特定的类型。函数的类型由它的返回类型和形参类型共同决定,与函数名无关,例如:

bool lengthCompare(const string &, const string &);

该函数类型是bool (const string &, const string &)。
如何声明一个指向该函数的指针?只需要用指针替换函数名即可:

bool (*pf)(const string &, const string &);    //pf是一个函数指针

如何使用函数指针
当把函数名作为一个值使用时,该函数自动地转换成指针,比如,把lengthCompare的地址赋给pf,下面两种写法是等价的:

pf = lengthCompare;
pf = &lengthCompare;

注意,指向不同函数类型的函数指针不存在转换规则,比如,上面的pf就只能指向bool (const string &, const string &)这种类型的函数,形参类型和返回值类型必须匹配。另外,如果函数指针有重载,则指针类型必须与重载函数中的某一个精确匹配。

typedef定义函数指针类型

typedef bool func(const string &, const string &);
typedef bool (*myFunc) (const string &, const string &);

可以看出,func是函数类型,而myFunc是指针类型,注意typedef 定义的是某种类型,并不是具体指向某个函数的函数指针。我们可以使用myFunc定义一个函数指针并初始化:

myFunc p_func = nullptr;

函数指针作形参
函数名可以直接作为实参使用,此时它被自动转换为指针(指向该函数的指针),比如:

void useBigger(const string &, const string &, lengthCompare);

自动将函数lengthCompare转换成指向该函数的指针。

返回函数指针
返回一个指向函数的指针,返回类型必须写成指针形式,因为编译器不会自动地将函数返回类型当成指针类型处理(与函数类型的形参不一样)。想要声明一个返回函数指针的函数,最简单的方法是使用类型别名(C++11新增,VS2010的编译器暂不支持)

using F = int (int*, int);    //F是函数类型
using PF = int (*) (int*, int);    //PF是指针类型

回调函数
下面这个栗子简单易懂,有助于了解回调函数

#include <iostream>
#include <cstdlib>

using namespace std;

typedef float (*p_func)(int, int, float);

//回调函数
float func_1(int a, int b, float c)
{
    return a*b*c;
}

//回调函数
float func_2(float a, float b, float c)
{
    return a+b+c;
}

float func_3(int a, int b, float c, p_func p)
{
    return (*p)(a,b,c);        //等价于 return *p(a,b,c);
}

float func_4(int a, int b, float c, float (*p_ff)(float, float, float))
{
    return (*p_ff)(a,b,c);    //等价于 return *p_ff(a,b,c);
}

//下面4个函数都是回调函数
float func_add(float a, float b, float c) 
{
    return a+b+c;
}
float func_sub(float a, float b, float c) 
{
    return a-b-c;
}
float func_mul(float a, float b, float c) 
{
    return a*b*c;
}
float func_div(float a, float b, float c) 
{
    return a/b/c;
}

int main()
{
    cout << "func_3 :" << func_3(3, 6, 2.5, func_1) << endl;
    cout << "func_4 :" << func_4(3, 6, 2.5, func_2) << endl << endl;

    //方法一:定义函数指针数组
    float(*f_p_a[4])(float, float, float);
    f_p_a[0] = func_add;
    f_p_a[1] = func_sub;
    f_p_a[2] = func_mul;
    f_p_a[3] = func_div;

    cout << "func_4(方法一) :" << func_4(3, 6, 2.5, f_p_a[0]) << endl;
    cout << "func_4(方法一) :" << func_4(3, 6, 2.5, f_p_a[1]) << endl;
    cout << "func_4(方法一) :" << func_4(3, 6, 2.5, f_p_a[2]) << endl;
    cout << "func_4(方法一) :" << func_4(3, 6, 2.5, f_p_a[3]) << endl << endl;

    //方法二:使用typedef
    typedef float (*f_p_a_type)(float, float, float);
    f_p_a_type ff_pp_aa[4] = {func_add, func_sub, func_mul, func_div};

    cout << "func_4(方法二) :" << func_4(3, 6, 2.5, ff_pp_aa[0]) << endl;
    cout << "func_4(方法二) :" << func_4(3, 6, 2.5, ff_pp_aa[1]) << endl;
    cout << "func_4(方法二) :" << func_4(3, 6, 2.5, ff_pp_aa[2]) << endl;
    cout << "func_4(方法二) :" << func_4(3, 6, 2.5, ff_pp_aa[3]) << endl << endl;

    system("pause");
    return 0;
}

运行结果:

 

标签:const,函数,int,float,c++,func,回调,string
From: https://www.cnblogs.com/warmlight/p/17876521.html

相关文章

  • 2023.12.4学习笔记(stm32跑马灯实验——库函数)
     STM32f4有七组引脚(GPIOx),每组引脚有16个IO口,每组由十个寄存器控制。   查找STM32引脚的功能,可以在STM32F04ZGT6文件50页左右查询,此文件所在的位置为硬件资料、芯片资料文件夹里。跑马灯实验思路步骤:1:使能时钟,调用函数RCC_AHB1PeriphClockCmd();       ......
  • 无涯教程-Erlang - equal函数
    该方法返回一个布尔值,表明一个字符串是否等于另一个字符串。如果字符串相等,则将返回true值,否则将返回false值。equal-语法equal(str1,str2)str1,str2  - 需要比较的2个字符串。equal-返回值如果两个字符串相等,它将返回true值,否则将返回false值。-module(helloLear......
  • 无涯教程-Erlang - len函数
    该方法返回特定字符串的长度len-语法len(str)str  - 这是需要确定字符数的字符串。len-返回值返回值是字符串中的字符数。-module(helloLearnfk).-import(string,[len/1]).-export([start/0]).start()->Str1="Thisisastring1",Len1=len(Str......
  • 无涯教程-Erlang - Is_Integer函数
    该方法检查数字是否为整数值。Is_Integer-语法Is_Integer(X)X - 一个数字值。Is_Integer-返回值如果指定为参数的数字是Integer值,则返回值为true,否则将返回false。-module(helloLearnfk).-export([start/0]).start()->Num=3,io:fwrite("~w",[is_int......
  • c++传参时 值传递和引用传递的区别
    值传递需要开辟存储空间并拷贝这个对象,引用传递只是给这个对象起了一个别名,不涉及开辟空间和拷贝操作,引用传递更高效值传递在调用函数中修改的不是原来的对象,而引用传递在调用函数中就能直接修改原来的对象举个例子体会一下:435.无重叠区间贪心算法求解,涉及到排序操作,排序函数......
  • 无涯教程-Erlang - Is_float函数
    该方法检查数字是否为浮点值。Is_float-语法Is_float(X)X - 一个数字值。Is_float-返回值如果指定为参数的数字为浮点型,则返回值为true,否则返回false。-module(helloLearnfk).-export([start/0]).start()->Num=3.00,io:fwrite("~w",[is_float(Num)]......
  • C/C++ 原生套接字抓取FTP数据包
    网络通信在今天的信息时代中扮演着至关重要的角色,而对网络数据包进行捕获与分析则是网络管理、网络安全等领域中不可或缺的一项技术。本文将深入介绍基于原始套接字的网络数据包捕获与分析工具,通过实时监控网络流量,实现抓取流量包内的FTP通信数据,并深入了解数据传输的细节,捕捉潜在......
  • 3、函数
    typescript为JavaScript函数添加了额外的功能:指定返回值类型指定传参的类型可选参数和默认参数剩余参数重载指定返回值类型functiongetInfo():number{return123;}console.log(getInfo());//123上面代码定义了一个返回值类型为数字的函数指定传参的类型......
  • C++:如何将 LLVM 嵌套到你的项目中去
    IDE:ClionLLVMcmake_minimum_required(VERSION3.9)project(clang_demo)find_package(LLVMREQUIREDCONFIG)message(STATUS"FoundLLVM${LLVM_PACKAGE_VERSION}")message(STATUS"UsingLLVMConfig.cmakein:${LLVM_DIR}")......
  • 无涯教程-Erlang - abs函数
    该方法返回指定数字的绝对值。abs-语法abs(X)X - 为绝对值功能指定一个值。abs-返回值返回值是数字的绝对值。-module(helloLearnfk).-export([start/0]).start()->Aabs=abs(-3.14),io:fwrite("~p~n",[Aabs]).当我们运行上述程序时,我们将得到以下......