基本含义及两个实例,均可在VS中运行。

前言

回调函数的定义是(根据百度百科):是一个通过函数指针调用的函数。如果把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用所指向函数的时候,就称为回调函数。C语言中的函数回调主要是通过函数指针来完成的,这给程序的开发提供了很大的灵活性。 

一、回调函数的含义

C语言程序中的回调函数要包括三个部分:主函数main()、中间函数library()、回调函数callback()。过程:main()在调用library()的时候,通过参数给library()传递了F1函数的指针(地址);在library()执行的时候,调用了F1函数;这就是回调(callback),F1就是回调函数。

c回调lua函数 c语言回调函数_函数指针

二、两个应用举例

1. 改写前的程序1

纸上得来终觉浅,通过语言叙述很难理解回调函数的用法。下面简单的通过函数调用方式实现的一个四则运算计算器,实现了加减乘除的功能,可以看出程序中冗杂的内容太多,进行4+6运算,运行后的结果为:

                                  

c回调lua函数 c语言回调函数_操作数_02

代码如下(运行时请自行添加头文件)

int add(int x, int y)
{
    return x + y;
}
int sub(int x, int y)
{
    return x - y;
}
int mul(int x, int y)
{
    return x * y;
}
int div(int x, int y)
{
    return x / y;
}
void menu()
{
    printf("****************************\n");
    printf("****  1.add       2.sub ****\n");
    printf("****  3.mul       4.div ****\n");
    printf("****        0.exit      ****\n");
    printf("****************************\n");
}
int main()
{
    int input = 0;
    do {
        menu();
        printf("请选择 :");
        scanf_s("%d", &input);
        switch (input)
        {
            int x = 0;
            int y = 0;
            int result = 0;
        case 1:
            printf("请输入两个操作数:");
            scanf_s("%d %d", &x, &y);
            result = add(x, y);
            printf("%d\n", result);
            break;
        case 2:
            printf("请输入两个操作数:");
            scanf_s("%d %d", &x, &y);
            result = sub(x, y);
            printf("%d\n", result);
            break;
        case 3:
            printf("请输入两个操作数:");
            scanf_s("%d %d", &x, &y);
            result = mul(x, y);
            printf("%d\n", result);
            break;
        case 4:
            printf("请输入两个操作数:");
            scanf_s("%d %d", &x, &y);
            result = div(x, y);
            printf("%d\n", result);
            break;
        case 0:
            printf("退出");
            break;
        default:
            printf("选择错误,请重新选择。\n");
            break;
        }
        
    } while (input);
    return 0;
}

2.用回调函数的方式改写后1

用回调函数的方式改写后,函数不仅代码量精简了,而且需要添加功能的时候也方便了许多。代码如下(示例):

int add(int x, int y)
{
    return x + y;
}
int sub(int x, int y)
{
    return x - y;
}
int mul(int x, int y)
{
    return x * y;
}
int div(int x, int y)
{
    return x / y;
}
void menu()
{
    printf("****************************\n");
    printf("****  1.add       2.sub ****\n");
    printf("****  3.mul       4.div ****\n");
    printf("****        0.exit      ****\n");
    printf("****************************\n");
}
int calc(int (*pf)(int, int))   //中间函数
{
    int x = 0;
    int y = 0;
    printf("请输入两个操作数:");
    scanf_s("%d %d", &x, &y);   
    printf("%d\n", pf(x,y));  //pf指向了对应的操作函数
}
int main()
{
    int input = 0;
    do {
        menu();
        printf("请选择 :");
        scanf_s("%d", &input);
        switch (input)
        {
            int result = 0;
        case 1:
            result = calc(add);  //将相应的操作函数地址传过去,故calc用函数指针接收
            break;
        case 2:
            result = calc(sub);
            break;
        case 3:
            result = calc(mul);
            break;
        case 4:
            result = calc(div);
            break;
        case 0:
            printf("退出");
            break;
        default:
            printf("选择错误,请重新选择。\n");
            break;
        }
    } while (input);
    return 0;
}

3.模拟Qsort函数的排序实现2

给一个数组arr[10]进行升序排序,模拟Qsort的方式,自行编写了一个b_sort()函数,为了使改程序可以排序任一格式的数据,所以用void*接传参。

void swap(char* buf1, char* buf2, int width)
{
	for (int i = 0; i < width; i++)
	{
		char tmp = *buf1;
		*buf1 = *buf2;
		*buf2 = tmp;
		buf1++;
		buf2++;
	}
}
void b_sort(void* base, int sz, int width, int (*cmp)(const void* e1, const void* e2))
{
	for (int i = 0; i < sz - 1; i++)  //排序的趟数
	{
		for (int j = 0; j < sz - 1 - i; j++)
		{
			if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
				//交换
				swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
		}
	}
}
int cmp_int(const void* e1, const void* e2)  //比较函数 返回int
{
	return *(int*)e1 - *(int*)e2;   
}
void print_arr(int arr[10], int sz)
{
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
}
void main()
{
	int arr[10] = { 0,3,4,1,2,5,6,7,9,8 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	b_sort(arr, sz, sizeof(arr[0]), cmp_int);
	print_arr(arr, sz);
}

总结

简单地总结了初学回调函数的过程。