函数指针和回调函数的事

一. 函数指针

关于函数指针的概念,可以想到一个整型指针指向的是一个整型,它的值是所指向对象的地址;一个字符串指针指向的是一个字符串,它的值是所指向字符串的首地址;因此,一个函数指针当然是一个指针变量了,它所指向的是一个函数,它的值就是所指向函数的入口地址

函数指针的定义如下:

typedef int data_type;

data_type (*pfun)(data_type, data_type);

上面的语句中定义了一个函数指针pfun,它表示指向一个返回值为data_type,参数为两个data_type类型的函数,上面第一个括号也就是(*pfun)的括号不能省略,否则就会变成:

data_type *pfun(data_type, data_type);

这样的话就为声明一个函数名为pfun的函数了,它的返回值为data_type*,参数为两个data_type类型的参数;

下面举个栗子说明函数指针的使用:

#include <iostream>
using namespace std;

typedef int data_type;

data_type add(data_type& a, data_type& b)
{
	return (a + b);
}

int main()
{
	data_type a = 2;
	data_type b = 3;
	data_type (*pfun)(data_type&, data_type&);
	pfun = &add;

	cout<<pfun(a, b)<<endl;
	return 0;
}

上面的程序中实现了一个函数add,并且定义了一个函数指针pfun指向这个函数,对函数指针的赋值和使用其他指针赋值语句一样,可以取函数的地址直接赋过去,但是因为函数名作为函数的入口地址,因此也可以不加取地址操作符“&”而直接将函数名赋给函数指针;要注意的是,函数指针的定义中,参数类型、个数和返回值必须和要指向的函数原型中的参数类型、个数和返回值一一对应

运行程序会得到结果5

指针在C/C++中是一个很灵活的变量,它可以指向与自己类型相同的不同存储空间,比如在数组中通常可以用指针来操纵,但这里值得注意的是,在一个数组或者字符串中使用指针进行加减操作会进行相应的移位指向下一个空间,有整型指针数组也就自然会有函数指针数组,它的数组成员都是一个个指向某个函数的函数指针,而在这样的数组中用指针进行加减操作就指向的是不同的函数指针也就是不同的函数了,单纯的对一个函数指针进行加减操作是不能够的,它并不会指向在当前函数上面或下面定义的某个函数。

像给一个整型指针赋值一样,可以给一个函数指针赋予不同的函数,这样就可以灵活的用一个指针来调用不同的函数而不用将每个函数都显式的写出来。

二. 回调函数

上面谈论的函数指针其实就是在为谈回调函数做铺垫,什么是回调函数?其实回调函数就是函数指针的一种使用,用户自己定义一个函数,将这个指向这个函数的函数指针作为参数传递给一个系统函数或者中间函数,当这个系统函数或中间函数执行的时候调用这个函数指针去执行用户定义的函数,那么用户定义的这个函数就叫做回调函数

为什么会有回调函数呢?难道就不能在一个函数里面直接调用用户所写的函数而不是传参过去吗?这种直接使用被调用函数的用法是在我们知道调用函数的内部实现机制的情况下直接写入的,那么,如果调用函数是系统内部函数或者是别人所给的一个函数借口呢?再如果有一种设计需求,要求执行一个函数但并不知道调用该函数的函数是如何操纵的呢?这样就没办法直接在调用函数内部写入被调用函数了,而是需要传入一个函数地址,至于该函数是如何调用如何来实现的,我们并不需要关心。

从上面的分析来看,回调函数的使用并不是你传给我,我调用你,而是还需要有一个起始的函数来调用系统函数或者中间函数将回调函数的地址作为参数给传过去,可画图说明:

图中的虚线,如果中间函数是系统函数,首先会由起始函数调用系统函数而由用户态进入内核态去由执行操作系统的函数,然后系统函数内部会执行调用用户实现的一个callback函数而从内核态再返到用户态去执行用callback函数,我个人认为也可以这么理解回调函数的回调二字,因此虚线是用户态和内核态的一个划分;但如果中间函数并不是系统函数,那么就一直会在用户态而不会接触到系统内部。

栗子时间:

#include <iostream>
using namespace std;

void print()
{
    //代码
    cout<<"hello..."<<endl;
    //代码
}

void say_hello(void (*pfun)(void))
{
    //代码
    pfun();
    //代码
}

int main()
{
    //代码
    say_hello(print);
    //代码
    return 0;
}

上面就是一个再简单不过的小栗子,注释掉的代码就可以是用户自己其他的实现,而如果栗子中的say_hello函数是系统函数或者是别人传过来的一个函数接口的话,其内部实现我们是无法干涉和了解的,因此,只需要将我们希望执行的回调函数地址给传过去,从而完成我们需要回调函数来完成的任务就可以了。

《完》

时间: 2024-12-30 04:08:31

函数指针和回调函数的事的相关文章

深入浅出剖析C语言函数指针与回调函数(二)

上一篇博文的地址: http://blog.csdn.net/morixinguan/article/details/65494239 这节,我们来看看函数指针与回调函数在Linux内核中的应用. 从上节我们了解到,函数指针和回调函数在开发者和用户之间的一个例子,那么这节,我将引用Linux内核中文件操作结构体来详细的说明. 我们首先来看到这个结构体,这段代码位于linux内核的include/linux/fs.h中,由于代码众多,我只截取几个最基本的例子: File_operations文件操

【C语言】函数指针与回调函数

在C语言中:指针是C语言的特色,有着各种各样的指针,普通的变量指针,常量指针,数组指针,指针数组,函数指针,指针函数.我们就讲一下函数指针与回调函数吧 首先关于函数指针,其实很简单. 对于一个函数指针来说,顾名思义,就是一个指向函数的指针,需要知道的是,对于指针而言,他总是存储一块地址,地址里面有着一个,一组,或者一块数据,在函数中,函数的存储是放在代码段的,每个函数都有着一个函数首地址,调用了这个地址相当于调用的这个函数. 具体的可以观看我的这篇博客,其中就通过在内存阶段改变栈帧返回值,成功的

函数指针,回调函数

函数指针的定义:返回值类型 ( * 指针变量名) (形参列表); 1:"返回值类型"说明函数的返回类型,"(指针变量名 )"中的括号不能省,括号改变了运算符的优先级.若省略整体则成为一个函数说明,说明了一个返回的数据类型是指针的函数,后面的"形参列表"表示指针变量指向的函数所带的参数列表. int func(int x); /* 声明一个函数 */ int (*f) (int x); /* 声明一个函数指针 */ f=func; /* 将func

函数指针、回调函数、系统调用区别

函数指针.回调函数.系统调用区别1.函数指针 1 int add(int a, int b) 2 { 3 return a+b; 4 } 5 6 int (*fp)(int,int); 7 8 int main() 9 { 10 int c; 11 fp = add; //有指针赋值操作,静态绑定 12 c = fp(2,4); 13 printf("c = %d\n",c); 14 return 0; 15 } 2.回调函数 1 int add(int a, int b) //回调函

c++函数指针用于回调函数

#include "stdafx.h" typedef int (*func)(int,int);class data{public: data() { a=12; b=13; } ~data() { } static int setdata(int c,int d) { return c+d; } int a; int b;protected:private: };void test(func _func,void* _data){ data* mydata=(data*)_data

函数指针与回调函数

一.函数指针 1.  函数指针就是一个指针变量,用来指向函数地址.正在运行的程序(进程)在内存中占据一定的空间.进程包括编译好的程序代码和需要使用的变量.因此,程序代码中的函数就是一些字符域,要得到一个函数地址,也就是得到这些字符域的起始地址. 2. 函数指针的三种形式:    指向普通C函数的函数指针 --- C语言中的函数指针    指向C++类静态成员函数的函数指针 --- C++    指向C++类非静态成员函数的函数指针 --- C++ 函数指针的本质自然也就是函数地址.  类成员函数

函数指针和回调函数

函数指针 函数指针是指向函数调用地址的指针.它和函数名究竟有什么关系呢?且看下文. 且看一小程序 首先,先请看下边程序: 1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 void func(string s) 6 { 7 cout << s << endl; 8 } 9 10 void (*pFunc)(string s); // 不能够写成 void *pFunc(s

函数指针,回调函数的定义和使用

一.函数指针 定义:函数指针是指向函数的指针变量,即本质是一个指针变量. int (*f) (int x); /* 声明一个函数指针 */ f=func; /* 将func函数的首地址赋给指针f */ 指向函数的指针包含了函数的地址,可以通过它来调用函数.声明格式如下:  类型说明符 (*函数名)(参数)其实这里不能称为函数名,应该叫做指针的变量名.这个特殊的指针指向一个返回整型值的函数.指针的声明笔削和它指向函数的声明保持一致.指针名和指针运算符外面的括号改变了默认的运算符优先级.如果没有圆括

深入浅出剖析C语言函数指针与回调函数(一)【转】

本文转载自:http://blog.csdn.net/morixinguan/article/details/65494239 关于静态库和动态库的使用和制作方法. http://blog.csdn.NET/morixinguan/article/details/52451612 今天我们要搞明白的一个概念叫回调函数. 什么是回调函数? 百度的权威解释如下: 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说