学术论文中遇到奇怪的C构造

Rit*_*ose 3 c function

代码说明:

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_msgprintf?在这种情况下,为什么功能名称(* log_msg)而不仅仅是log_msg

ken*_*ytm 6

void (* log_msg)(char *msg)实际上是一个函数指针.您可以将其视为

typedef void (*LoggerFunctionPointer)(char* msg);

LoggerFunctionPointer log_msg = printf;
Run Code Online (Sandbox Code Playgroud)

是的,它映射log_msgprintf但不是,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)

然后,在不更改其他源代码的情况下,可以禁止所有日志记录.


(顺便说一句,示例代码不正确,因为签名printfint printf(const char*, ...).为了避免隐式转换,log_msg应该声明为

int (*log_msg)(const char*, ...) = printf;
Run Code Online (Sandbox Code Playgroud)

)