一、C语言回调函数
1、回调函数概念
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

简单点来说,就是主函数 Main program 调用函数 Library function 的时候,函数Main program 通过参数给函数 Library function传递了另外一个函数Callback function 的指针。在函数 Library function 执行的过程中,函数Library function 调用了函数Callback function,这个动作就叫做回调(Callback),而先被当做指针传入、后面又被回调的函数Callback function就是回调函数。
2、回调函数的作用
回调似乎只是函数间的调用,和普通函数调用没啥区别,但仔细一看,可以发现两者之间的一个关键的不同:在回调中,主程序把回调函数像参数一样传入库函数。这样一来,只要我们改变传进库函数的参数,就可以实现不同的功能,并且丝毫不需要修改库函数的实现,实现解耦。
#include<stdio.h>
#include<softwareLib.h> // 包含Library Function所在读得Software library库的头文件
// Callback Function
// 只需要编写需要的回调函数即可
int Callback()
{
// TODO
return 0;
}
int main() // Main program
{
// TODO
Library(Callback);
// TODO
return 0;
}
3、回调函数的简单使用
#include<stdio.h>
int Callback_1() // Callback Function 1
{
printf("Hello, this is Callback_1 ");
return 0;
}
int Callback_2() // Callback Function 2
{
printf("Hello, this is Callback_2 ");
return 0;
}
//形参是回调函数的指针,返回值是回调函数的返回值
int Handle(int (*Callback)())
{
printf("Entering Handle Function. \n");
//运行回调函数
Callback();
printf("Leaving Handle Function. \n");
}
int main()
{
printf("Entering Main Function. \n");
Handle(Callback_1);
Handle(Callback_2);
printf("Leaving Main Function. \n");
return 0;
}
4、回调函数进阶版
四则运算的简单回调函数.
#include <stdio.h>
#include <stdlib.h>
/****************************************
* 函数指针结构体,定义四个函数指针分别指向这四个函数
***************************************/
typedef struct _OP {
float (*p_add)(float, float);
float (*p_sub)(float, float);
float (*p_mul)(float, float);
float (*p_div)(float, float);
} OP;
/****************************************
* 加减乘除函数
***************************************/
float ADD(float a, float b)
{
return a + b;
}
float SUB(float a, float b)
{
return a - b;
}
float MUL(float a, float b)
{
return a * b;
}
float DIV(float a, float b)
{
return a / b;
}
/****************************************
* 初始化函数指针
***************************************/
void init_op(OP *op)
{
op->p_add = ADD;
op->p_sub = SUB;
op->p_mul = &MUL;
op->p_div = &DIV;
}
/****************************************
* 当做库函数,以函数指针为参数,通过它来调用不同的函数
***************************************/
float add_sub_mul_div(float a, float b, float (*op_func)(float, float))
{
return (*op_func)(a, b);
}
int main(int argc, char *argv[])
{
OP *op = (OP *)malloc(sizeof(OP));
init_op(op);
/* 直接使用函数指针调用函数 */
printf("ADD = %f, SUB = %f, MUL = %f, DIV = %f\n", (op->p_add)(1.3, 2.2), (*op->p_sub)(1.3, 2.2),
(op->p_mul)(1.3, 2.2), (*op->p_div)(1.3, 2.2));
/* 调用回调函数 */
printf("ADD = %f, SUB = %f, MUL = %f, DIV = %f\n",
add_sub_mul_div(1.3, 2.2, ADD),
add_sub_mul_div(1.3, 2.2, SUB),
add_sub_mul_div(1.3, 2.2, MUL),
add_sub_mul_div(1.3, 2.2, DIV));
return 0;
}
二、C语言简单日志系统
简答的不同等级日志打印底层,可以控制日志输出,打印出具体的行号,函数名等,可以用来当做参考,和spring的日志系统有点像
新建log.h
#ifndef _EM_LOG_H
#define _EM_LOG_H
#include<stdio.h>
#include<stdarg.h>
#define OPEN_LOG 1
#define LOG_LEVEL LOG_DEBUG
#define LOG_SAVE 1
typedef enum
{
LOG_DEBUG=0,
LOG_INFO,
LOG_WARN,
LOG_ERROR,
}E_LOGLEVEL;
void EM_LOG(const int level, const char *fun, const int line, const char *fmt,...);
#define EMLOG(level,fmt...) EM_LOG(level,__FUNCTION__,__LINE__,fmt)
#endif
新建log.c
#include "log.h"
// 定义不同等级的日志级别
char* EM_LOGLevelGet(const int level){
if(level==LOG_DEBUG){
return "DEBUG";
} else if(level==LOG_INFO){
return "INFO";
} else if(level ==LOG_WARN){
return "LOG_WARN";
} else if(level ==LOG_ERROR){
return "LOG_ERROR";
}
return "UNKNOW";
}
// 日志输出,可以定位行号、方法名
void EM_LOG(const int level, const char *fun, const int line, const char *fmt,...){
#ifdef OPEN_LOG
va_list arg;
va_start(arg, fmt);
char buf[1+vsnprintf(NULL,0, fmt, arg)];
vsnprintf(buf,sizeof(buf), fmt, arg);
va_end(arg);
if(level>=LOG_LEVEL)
printf("[%s] [%s %d] %s\n",EM_LOGLevelGet(level),fun,line,buf);
#endif
}
int main(){
int a=10,b=11;
EMLOG(LOG_DEBUG,"app start");
EMLOG(LOG_INFO,"A=%d %d",a,b);
EMLOG(LOG_WARN,"app LOG_WARN");
EMLOG(LOG_ERROR,"app LOG_ERROR");
return 0;
}
参考文章:
https://www.runoob.com/w3cnote/c-callback-function.html
https://segmentfault.com/a/1190000008293902
https://www.bilibili.com/video/BV1EB4y1N7iD
本文详细介绍了C语言中的回调函数,包括其概念、作用、简单使用及进阶应用,展示了如何通过函数指针实现四则运算。此外,还提供了一个简单的C语言日志系统示例,能够按不同等级打印日志,方便调试和问题排查。
886

被折叠的 条评论
为什么被折叠?



