代码说明:
void (* log_msg)(char *msg)
=printf;
void change_and_log(int *buffer, int offset, int value){
buffer[offset] = value;
log_msg("changed");
}
Run Code Online (Sandbox Code Playgroud)
我最关心的是第一部分:
首先,签名void (* log_msg)(char *msg)是什么意思?这段代码只是将函数映射log_msg到printf?在这种情况下,为什么功能名称(* log_msg)而不仅仅是log_msg?
void (* log_msg)(char *msg)实际上是一个函数指针.您可以将其视为
typedef void (*LoggerFunctionPointer)(char* msg);
LoggerFunctionPointer log_msg = printf;
Run Code Online (Sandbox Code Playgroud)
是的,它映射log_msg到printf但不是,log_msg它不是一个函数,而是一个指向函数的指针printf.
使用函数指针的优点是log_msg可以在运行时切换.例如,您可以在界面中提供一个开关
void no_log_msg(char* msg) {}
...
if (enable_debug) {
log_msg = printf;
} else {
log_msg = no_log_msg;
}
Run Code Online (Sandbox Code Playgroud)
然后,在不更改其他源代码的情况下,可以禁止所有日志记录.
(顺便说一句,示例代码不正确,因为签名printf是int printf(const char*, ...).为了避免隐式转换,log_msg应该声明为
int (*log_msg)(const char*, ...) = printf;
Run Code Online (Sandbox Code Playgroud)
)