代码说明:
void (* log_msg)(char *msg)
=printf;
void change_and_log(int *buffer, int offset, int value){
buffer[offset] = value;
log_msg("changed");
}
我最关心的是第一部分:
首先,签名void (* log_msg)(char *msg)
是什么意思?此代码是否只是将函数log_msg
映射到printf
?在这种情况下,为什么函数名称为(* log_msg)
,而不仅仅是log_msg
?
答案 0 :(得分:6)
void (* log_msg)(char *msg)
实际上是一个函数指针。您可以将其视为
typedef void (*LoggerFunctionPointer)(char* msg);
LoggerFunctionPointer log_msg = printf;
是的,它将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;
}
然后,在不更改其他源代码的情况下,可以禁止所有日志记录。
(顺便说一下,示例代码不正确,因为printf
的签名是int printf(const char*, ...)
。为避免隐式转换,log_msg
应声明为
int (*log_msg)(const char*, ...) = printf;
)
答案 1 :(得分:2)
前两行是建立一个函数指针(因此是*),该函数名为log_msg,然后将其设置为指向printf - 之后调用log_msg最终调用printf
答案 2 :(得分:2)
函数指针的类型为R (*)(Args...)
,其中R
和Args...
将替换为返回类型和参数(如果有)。它被读作“指向函数的指针,该函数接受参数Args...
并返回R
。”
您的代码将更容易阅读:
// print_function is a type that is a function pointer
typedef void (*print_function)(char *msg);
// log_msg is a variable of the type print_function: it points to a function
print_function log_msg = printf; // point to printf
之后,它只是通过函数指针调用该函数。
答案 3 :(得分:2)
log_msg
是function pointer,特别是“指向char *
并返回void
的函数的指针”。在这种情况下,它仅用作printf
的别名(但可以指向具有相同参数和返回类型的任何函数)。
C中函数指针的语法起初可能非常令人生畏。