这是将函数传递给结构的正确方法吗?

Is this a correct way to pass a function into a struct?

我查看了这个问题,但找不到直接参考。我是函数指针(和 C)的新手,所以我还不知道可以做的所有技巧:)

我有效地得到了一个函数:

void select_comparator(My_Struct *structure, int (*comp)(int x, int y)) {
    ...

...其中 My_Struct 有原型:

typedef struct my_struct {
    int (*comp)(int x, int y);
} My_Struct;

取模一些小细节。我只想知道以下语法是否正确:

void select_comparator(My_Struct *structure, int (*comp)(int x, int y)) {
    structure->comp = comp;
}

这似乎太容易了,我很担心。

没问题:这是 中回调的基础。只需确保函数指针的签名与结构中定义的类型相匹配。当你在一个大型项目中使用它时,它变得非常棘手,人们忘记检查函数指针是否有效或 void,以及参数等

代码清单


/*******************************************************************************
 * Preprocessor directives.
 ******************************************************************************/
#include <stdio.h>


/*******************************************************************************
 * Data types.
 ******************************************************************************/
typedef struct my_struct {
    int (*comp)(int x, int y);
} My_Struct;


/*******************************************************************************
 * Function prototypes.
 ******************************************************************************/
int c(int a, int b);
void select_comparator(My_Struct *structure, int (*comp)(int x, int y));


/*******************************************************************************
 * Function definitions.
 ******************************************************************************/
/*----------------------------------------------------------------------------*/
int main(void)
{
    My_Struct s;

    select_comparator(&s, &c);
    s.comp(1, 2);

    return 0;
}

/*----------------------------------------------------------------------------*/
void select_comparator(My_Struct *structure, int (*comp)(int x, int y))
{
    structure->comp = comp;
}

/*----------------------------------------------------------------------------*/
int c(int a, int b)
{
    int ret = 0;
    if (a < b) {
        ret = (-1);
    } else if (a > b) {
        ret = 1;
    }

    return ret;
}

代码没问题

不过请注意,函数指针在 C 中的语法非常糟糕,尤其是从函数传递 to/returned 时。尝试写类似 "function returning function-pointer and taking function-pointer as parameter" 的东西,您很快就会意识到语法是纯粹的疯狂。

因此,使用 typedef 将函数指针 "fall in line" 与语言的其余部分一起使用是个好主意。

你的代码可以这样写:

typedef int comp_t (int x, int y); // typedef a function type

typedef struct {
    comp_t* comp;   // pointer to such a function type
} My_Struct;

void select_comparator(My_Struct *structure, comp_t* comp) {
    structure->comp = comp;
}

现在代码变得更易于阅读,函数指针的行为与任何其他指针非常相似。