函数名称与Struct中指针的可变性

时间:2013-01-27 00:09:51

标签: c

以下代码片段中的指针函数声明允许我改变struct中每个函数的名称,对吗?这只是假设,所以这些名字还没有结果。

标题文件

typedef struct
{
    bool (*enabled)(uint32_void);
    void (*start)(uint32_t);
    void (*stop)(uint32_t);
    bool (*expired)(void);
} battle_star_gallactica;

C档案

static bool Battle_v0_enabled (void) { ... }
static void Battle_v0_start (uint32_t) { ... }
static void Battle_v0_stop (uint32_t) { ... }
static bool Battle_v0_stop (void) { ... }

const battle_star_gallactica battle_v0 =
{
    enabled,
    start,
    stop,
    expired
};
...

一个示例使用

battle_v0.start(1000);

对于其他版本(例如v1或v2而不是v0),将重复使用C文件片段。

这是如何运作的?

修改

更正后的代码:

标题文件

typedef struct
{
    bool (*enabled)(uint32_void);
    void (*start)(uint32_t);
    void (*stop)(uint32_t);
    bool (*expired)(void);
} battle_star_gallactica;

extern const battle_star_gallactica battle_v0;
extern const battle_star_gallactica battle_v1;
...

C档案

static bool Battle_v0_enabled (void) { ... }
static void Battle_v0_start (uint32_t val) { ... }
static void Battle_v0_stop (uint32_t val) { ... }
static bool Battle_v0_expired (void) { ... }

const battle_star_gallactica battle_v0 =
{
    Battle_v0_enabled,
    Battle_v0_start,
    Battle_v0_stop,
    Battle_v0_expired
};
...

一个示例使用

battle_v0.start(1000);

3 个答案:

答案 0 :(得分:2)

是。但是你有一些问题:

1)Battle_v0_stop定义了两次 2)在启动battle_v0时,您需要使用Battle_v0_

作为前缀值

然后你可以这样做:

battle_v0.enabled()

但我会使用currnet battle star galactic并使用它:

const battle_star_gallactica bsg = battle_v0;
bgs.enabled()

答案 1 :(得分:1)

您没有名为enabledstart的功能,等等。使用函数指针初始化对象时,将指针传递给实际的函数名称(即Battle_v0_start)。也就是说,重要的是要注意你的类型不匹配。它应该是Battle_v0_start(uint32_t),而不是void

但是,在正确初始化之后,您只需拨打your_obj.your_struct_function_name(your_arguments, ...)即可。在您的情况下,battle_v0.start(1000)将调用Battle_v0_start(如果您将此函数传递给指针)。您可以像大多数其他指针类型一样考虑这一点。

答案 2 :(得分:1)

您必须将目标函数分配给每个函数指针,例如

battle_v0.enabled = Battle_V0_enabled;
battle_v0.start   = Battle_V0_start;
// etc.

const battle_star_galactica battle_v0 = {
    Battle_V0_enabled,
    Battle_V0_start,
    Battle_V0_stop,
    Battle_V0_expired
};

然后你可以通过指针调用函数:

battle_v0.start(1000);  // or battle_v0.(*start)(1000)

将使用值1000调用Battle_V0_start函数。

请注意,函数签名(返回类型和参数的数量/类型)必须匹配;例如,您声明start的函数指针采用类型为uint32_t的参数,但Battle_V0_start不带参数。其中一个或另一个需要改变才能匹配。

void Battle_V0_start(uint32_t val) { ... }