值与函数指针的并集

时间:2019-02-04 13:32:48

标签: c unions

我在努力使用工会。为什么我无法将函数指针传递到联合的位置?任何帮助将不胜感激。

编辑:删除了typedef

2019-Feb-04

3 个答案:

答案 0 :(得分:4)

首先,此定义无效:

union U {
    typedef int(*fnPtr)(int);
    int i;
};

typedefstruct内不能有union。删除typedef将为您提供正确的定义:

union U {
    int(*fnPtr)(int);
    int i;
};

第二个问题在这里:

int b = f (a, OPTION_1, &multiply_by_two);

函数f需要一个union U,但是您正在传递一个int (*)(int)。这些类型不兼容。仅仅因为联合具有该类型的成员并不意味着您可以在使用联合的任何位置使用该类型。您需要创建一个并集,设置适当的字段,然后将其传递给函数。

union U u;
u.fnPtr = multiply_by_two;
int b = f (a, OPTION_1, u);

答案 1 :(得分:2)

在主功能中,尝试以下操作:

int main()
{
  ...
  union U myUnion;
  myUnion.fnPtr = &multiply_by_two;
  int b = f (a, OPTION_1, myUnion);
  ...
}

而且,联合定义不正确,您需要删除typedef

答案 2 :(得分:1)

只需添加其他答案即可:通常将其称为变量数据类型,将类型枚举与struct一起保留在union中是有意义的,因为您将传递无论如何,总是如此。

所以我建议将两者都放在struct中:

enum var_type
{
    VAR_INT = 0,
    VAR_FUNC = 1
};

struct variant
{
    // contains the type of the stored value
    enum var_type type;

    // contains the actual value
    union {
        int(*fnPtr)(int);
        int i;
    };    
};

然后您可以具有用于创建每个子类型的单独函数,以简化实例化:

// wrap the int value in the variant struct
struct variant variant_create_int(int i)
{
    return (struct variant){ .type = VAR_INT, .i = i };
}

// wrap the functino pointer in the variant struct
struct variant variant_create_func(int(*fnPtr)(int))
{
    return (struct variant){ .type = VAR_FUNC, .fnPtr = fnPtr };
}

表示您的main将执行以下操作:

// create variant of type 'VAR_FUNC'
struct variant var = variant_create_func(&multiply_by_two);

,然后向前传递var结构。