C语言中的回调函数调用过程以及函数指针使用

回调函数比喻:

你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。

在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。

回调函数是一个程序员不能显式调用的函数;通过将回调函数的地址传给调用者从而实现调用。

回调函数使用是必要的,在我们想通过一个统一接口实现不同的内容,这时用回掉函数非常合适。

比如,我们为几个不同的设备分别写了不同的显示函数:

void TVshow(); void ComputerShow(); void NoteBookShow()...等等。

这是我们想用一个统一的显示函数,我们这时就可以用回掉函数了。void show(void (*ptr)()); 使用时根据所传入的参数不同而调用不同的回调函数。

不同的编程语言可能有不同的语法,下面举一个c语言中回调函数的例子, 其中一个回调函数不带参数,另一个回调函数带参数。

// Test.c

#include <stdlib.h>
#include <stdio.h>

int Test1()
{
        int i;
        for (i=0; i<30; i++) {
                printf("The %dth charactor is:%c\n", i, (char)(‘a‘+i%26));
        }

        return 0;
}

int Test2( int num)
{
        int i;
        for (i=0; i< num; i++) {
                printf("The %dth charactor is:%c\n", i, (char)(‘a‘+i%26));
        }

        return 0;
}

void Caller1( int (*ptr)() )              //指向函数的指针作函数参数
{
        (*ptr)();
}

void Caller2(int n, int (*ptr)(int) )        //指向函数的指针作函数参数,这里第一个参数是为指向函数的指针服务的,
{                                         //不能写成void Caller2(int (*ptr)(int n)),这样的定义语法错误。

        (*ptr)(n);
}

int main()
{
        printf("***************************\n");
        Caller1(Test1); //相当于调用Test1();
        printf("&&&&&&&**********************\n");
        Caller2(5, Test2);//相当于调用Test2(5);
        return 0;
}

以上通过将回调函数的地址传给调用者从而实现调用,但是需要注意的是带参回调函数的用法。

要实现回调,必须首先定义函数指针。函数指针的定义这里稍 微提一下。比如:

int (*ptr)(); 

这里ptr是一个函数指针,其中(*ptr)的括号不能省略,因为括号的优先级高于星号,那样就成了一个返回类型为指向整型的指针类型的函数声明了。

参考链接

http://www.zhihu.com/question/19801131/answer/13005983

http://www.blogjava.net/huyi2006/articles/180169.html

原文地址:https://www.cnblogs.com/Free-Thinker/p/8393628.html

时间: 2024-11-09 10:43:51

C语言中的回调函数调用过程以及函数指针使用的相关文章

在C语言中以编程的方式获取函数名

调试常用的 __FILE__, __FUNCTION__, __LINE__ 调试常用的 __FILE__, __FUNCTION__, __LINE__ 没想到 VC6 不支持 __FUNCTION__ 所以我写了如下的奇怪代码 //用来记录当前行和当前函数//也可说是记录 堆栈void log_stack(const char *file, int line, const char * function); //当然还要对 __FUNCTION__ 宏作点修饰,因为这个宏只是在函数里面才起作

C语言中的回调

回调函数就是通过一个函数指针调用的函数,如果把函数的指针作为实参传给另外一个一个函数,当这个指针被用来调用它指向的函数时,这个过程就是回调. c语言中的函数原型如下:void method(); 对应的函数指针声明:void (*)(),如果给该函数指针取一个变量名称p,则p指向这个函数的,可以声明为 void (*p)(),该函数指针无参数,返回值为void类型. 我们看一下如下例子: void method(){ printf("测试函数指针....\n"); } int main

C语言中的回调函数(Callback Function)

1 定义和使用场合 回调函数是指 使用者自己定义一个函数,实现这个函数的程序内容,然后把这个函数(入口地址)作为参数传入别人(或系统)的函数中,由别人(或系统)的函数在运行时来调用的函数.函数是你实现的,但由别人(或系统)的函数在运行时通过参数传递的方式调用,这就是所谓的回调函数.简单来说,就是由别人的函数运行期间来回调你实现的函数. 这一设计允许了底层代码调用在高层定义的子程序(如图1-1所示).C语言中回调函数主要通过函数指针的方式实现. 图1-1 回调函数在软件系统的调用结果 回调的用途十

C语言中有关外部函数调用的问题

首先指出一点,我们通常所说的编译器并非仅指编译器,确切来说是编译工具链,里面包括了预编译器.编译器.汇编器和连接器. 对于外部函数实体(处于调用函数所在源文件之外的其他源文件中的函数),是在链接过程中,才会被寻找和添加进程序,一旦没有找到函数实体,就会报错,无法成功链接. 而外部函数的声明(一般声明在头文件中)只是令程序顺利通过编译而已,此时并不需要搜索到外部函数的实体. 当然,外部函数实体所在源文件也需要被编译为目标文件,至于链接时 如何找到该函数实体,这由链接器完成. 另外,头文件和对应源文

C语言中值得深入知识点----数组做函数参数、数组名a与&amp;a区别、数组名a的&quot;数据类型&quot;

1.数组作为函数参数 C语言中,数组做为函数的参数,退化为指针.数组作为参数传给函数时,传的是指针而不是数组,传递的是数组的首元素的地址.这里我们以将以整形变量排序来讲解. void sortArray(int a[] ,int num )以及void sortArray(int a[100] ,int num )都可以用void sortArray(int *a ,int num )表示.一般来说函数参数如果为数组,可以有两个参数,一个是数组名,一个是数组长度.对于排序而已,一般是要知道给定数

c语言中的部分字符串和字符函数

// // main.c // homeWork1230 // // #include <stdio.h> #include <string.h> #include <ctype.h> int main(int argc, const char * argv[]) { //// strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串.如果是,则该函数返回str2在str1中首次出现的地址:否则,返回NULL. // printf("

002_解析go语言中的回调函数

回调函数是一种特殊的函数写法,在很多场景中发挥广泛的作用.但是对于初学者来说,回调函数是比较头疼的一个东西,不太好懂,笔者研究了一番,以网上的一个例子详细说明一下 首先看一个代码示例(来源于网上) package main import "fmt" type Callback func(x, y int) int func main() { x, y := 1, 2 fmt.Println(test(x, y, add)) } //实现回调 func test(x, y int, ca

C语言中数组名作为参数进行函数传递

用数组名作函数参数与用数组元素作实参有几点不同. 1) 用数组元素作实参时,只要数组类型和函数的形参变量的类型一致,那么作为下标变量的数组元素的类型也和函数形参变量的类型是一致的.因此,并不要求函数的形参也是下标变量.换句话说,对数组元素的处理是按普通变量对待的.用数组名作函数参数时,则要求形参和相对应的实参都必须是类型相同的数组,都必须有明确的数组说明.当形参和实参二者不一致时,即会发生错误. 2) 在普通变量或下标变量作函数参数时,形参变量和实参变量是由编译系统分配的两个不同的内存单元.在函

C语言中模拟实现strcpy,strstr,strcat函数

在C中,要模拟实现这几个库函数,是对指针的传参与函数的调用的考察,代码如下,仅供参考 strcpy函数: #include <assert.h> char* my_strcpy(char* dest, const char* src) { assert(dest);//断言指针的有效性 assert(src); char*pa = dest; while (*dest++ = *src++) ; return pa; } strstr函数: int my_strstr(const char*s