如何打印函数指针的级联名称?

时间:2017-06-30 07:53:18

标签: c function pointers display

我正在处理函数指针示例,我开发了4个简单函数并将它们分配给函数指针数组,然后我运行代码并为4个函数工作,但后来我还想打印函数的名称。

我了解了__func__并且只打印了当前函数的名称,所以无论如何将__func__分配给函数指针或其他方法来打印函数的名称?

这是我现在正在研究的例子:

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>


int add(int x, int y);
int sub(int x, int y);
int mul(int x, int y);
int divide(int x, int y);


int main() {
    int m = 6;
    int n = 10;
    int res,i;


    int (*fun[4])(int,int)={add,sub,mul,divide};

    for (i=0;i<4;i++)
    {
        printf("result of %s operation\n",__func__=fun[i]);
    }
}

int add(int x, int y) {
int result = x + y;
return result;
}

int sub(int x, int y) {
int result = x - y;
return result;
}

int mul(int x, int y) {
int result = x * y;
return result;
}

int divide(int x, int y) {
int result = x / y;
return result;
}

正如您所看到的,我正在尝试将__func__分配给函数指针,但当然它不起作用。

4 个答案:

答案 0 :(得分:3)

每个函数中的__func__常量只能在运行时访问。这意味着如果你想使用那个,你必须在调用函数时抓住它。像这样:

typedef int calc_func_t (int x, int y, const char** func);

int add(int x, int y, const char** func);
...

calc_func_t* fun[4] = {add,sub,mul,divide};

for (i=0;i<4;i++)
{
    const char* func;
    int result = fun[i](1,1,&func);
    printf("result of %s operation %d\n", func, result);
}

...

int add(int x, int y, const char** func) 
{
  int result = x + y;
  *func = __func__;
  return result;
}

...

如果您想知道在编译时命名的函数然后再使用该信息,最简单和最好的方法是创建一个查找表:

typedef struct
{
  calc_func_t* func;
  const char*  name;
} calc_func_info_t;

const calc_func_info_t func_info [] =
{
  {add, "add"},
  {sub, "sub"},
  ...
};

答案 1 :(得分:2)

编译代码默认不包含函数和符号名称。您可以使用一些宏来创建包含要包含在已编译二进制文件中的函数名的常量字符串:

#include <stdio.h>

// function call type
typedef void fn_call();

// record describing one function
typedef struct fn_record {

    const char *name; // function's name as a constant string
    fn_call *call; // function call

} fn_record;

// the functions to be called and named
void fna() { printf("called fna\n"); }
void fnb() { printf("called fnb\n"); }
void fnc() { printf("called fnc\n"); }

// macro, that generates record for each function, it creates 
// string like { "fna", fna } to save You typing
#define FN_RECORD(f) { #f, f }

// now define array of functions records
fn_record fns[3] = {
    FN_RECORD(fna),
    FN_RECORD(fnb),
    FN_RECORD(fnc)
};

// ... which becomes:
// fn_record fns[3] = {
//     { "fna", fna },
//     { "fnb", fnb },
//     { "fnc", fnc }
// };


int main(void) {

    int i;

    // ... use it whatever You like
    for (i = 0; i < 3; i++) {

        printf("%s\n", fns[i].name);
        fns[i].call();
    }

    return 0;
}

答案 2 :(得分:0)

基本上没有办法。

// A function declaration
void MyFunction(void);

// a pointer to the function
void (*fnPointer)(void) = MyFunction;

// No way to retrieve function name "MyFunction" from fnPointer

当然,如果你有一组已知的可能分配给指针的函数,你可以明确地比较它们。

此外,您可以将存储的函数指针更改为与函数名称组合。可能类似于以下内容:

struct FunctionPointerContainer
{
    void (*fnPointer)(void);
    char* fnName;
};

#define MakeFunctionPointer(fn) FunctionPointerContainer { fn, #fn }

// later
struct FunctionPointerContainer myPointer = MakeFunctionPointer(MyFunction);
myPointer.fnPointer(); // call
myPointer.fnName; // the function name

答案 3 :(得分:0)

  

我正在使用函数指针示例

所以,据我所知,你的例子是用于教育目的,不是吗?在这种情况下,我会这样做,因为它可以不会混淆使用你的例子的学生来学习函数指针是如何工作的。

  

我了解了__func__并且只打印了当前函数的名称

尽管其他答案显示了非常好的智能解决方案如何在其之外使用函数名称,从简单的角度来看我仍然会使用__func__,因为它通常有效,在里面被调用的函数:

#include <stdio.h>
#define print_info(format, ...) \
    printf("Function '%s' is called with parameters: "format"\n", \
    __func__, __VA_ARGS__)

int add(int x, int y);
int sub(int x, int y);
int mul(int x, int y);
int divide(int x, int y);

int main() {
    int m = 6, n = 10, i;    
    int (*fun[4])(int,int) = { add, sub, mul, divide };

    for (i = 0; i < 4; ++i)
        printf("-- result is: %d\n", fun[i](n, m));

    return 0;
}

int add(int x, int y) {
    print_info("%d, %d", x, y);
    return x + y;
}

int sub(int x, int y) {
    print_info("%d, %d", x, y);
    return x - y;
}

int mul(int x, int y) {
    print_info("%d, %d", x, y);
    return x * y;
}

int divide(int x, int y) {
    print_info("%d, %d", x, y);
    return x / y;
}