代码之家  ›  专栏  ›  技术社区  ›  Ritwik Bose

学术论文中的奇怪C结构

  •  3
  • Ritwik Bose  · 技术社区  · 14 年前

    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) 不仅仅是 日志\u消息 ?

    4 回复  |  直到 14 年前
        1
  •  2
  •   GManNickG    14 年前

    它是一个 function pointer .

    R (*)(Args...) ,在哪里 R Args... 替换为返回类型和参数(如果有)。它被读取为“指向接受参数的函数的指针” 参数。。。

    // 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
    

    后来,它只是通过一个函数指针调用那个函数。

        2
  •  6
  •   kennytm    14 年前

    void (* log_msg)(char *msg)

    typedef void (*LoggerFunctionPointer)(char* msg);
    
    LoggerFunctionPointer log_msg = printf;
    

    是的,它是地图 log_msg printf 不是函数,而是指向函数的指针 .

    使用函数指针的优点是 日志\u消息 可以在运行时切换。例如,您可以在接口中提供一个开关

    void no_log_msg(char* msg) {}
    ...
    if (enable_debug) {
      log_msg = printf;
    } else {
      log_msg = no_log_msg;
    }
    

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


    打印F int printf(const char*, ...) . 为了避免隐式投射, 日志\u消息 应声明为

    int (*log_msg)(const char*, ...) = printf;
    

        3
  •  2
  •   Will A    14 年前

    最上面的两行正在建立一个函数 指针 (因此名为*)的函数名为log\u msg,然后将其设置为指向printf,之后对log\u msg的调用将最终调用printf。

        4
  •  2
  •   Ismail Badawi    14 年前

    log_msg 是一个 function pointer ,尤其是指向 char * void ". 在本例中,它只是用作 printf (但可以指向具有相同参数和返回类型的任何函数)。