简体   繁体   English

价值和功能指针的结合

[英]union of value and function pointer

I am struggling with using unions. 我正在努力使用工会。 Why am I unable to pass the function pointer to where the union would be? 为什么我无法将函数指针传递给union所在的位置? Any help would be greatly appreciated. 任何帮助将不胜感激。

Edit: removed a typedef 编辑:删除了一个typedef

#include <stdio.h>

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

enum E {
    OPTION_0 = 0,
    OPTION_1 = 1
};

int multiply_by_two (int x) {
    return 2 * x;
}

int f (int x, enum E e, union U u) {
    switch (e) {
        case OPTION_0:
            /* Return the sum */
            return x + u.i;
        case OPTION_1:
            /* Return 2 * x */
            return u.fnPtr (x);
    }
}

int main (void) {
    int a;
    scanf ("%d", &a);
    int b = f (a, OPTION_1, &multiply_by_two);
    printf ("%d\n", b);
    return 0;
}

First, this definition is not valid: 首先,这个定义无效:

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

You can't have a typedef inside of a struct or union . 您不能在structunion包含typedef Removing the typedef will give you a proper definition: 删除typedef将为您提供正确的定义:

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

The second problem is here: 第二个问题在这里:

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

The function f expects a union U , but you're passing it a int (*)(int) . 函数f需要一个union U ,但是你传递的是一个int (*)(int) Those types are not compatible. 这些类型不兼容。 Just because the union has a member of that type doesn't mean you can use that type wherever you would use the union. 仅仅因为union具有该类型的成员并不意味着您可以在任何使用union的地方使用该类型。 You need to create a union, set the proper field, then pass that to the function. 您需要创建一个联合,设置正确的字段,然后将其传递给该函数。

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

In main function, try this: 在main函数中,试试这个:

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

And also, the union definition is not correct, you need to remove typedef . 而且,联合定义不正确,您需要删除typedef

Just to add to other answers: this is usually called a variant data type, and it makes sense to keep the type enum in a struct , along with the union , since you will be passing it around all the time anyway. 只是为了添加其他答案:这通常被称为变量数据类型,并且将类型枚举保留在struct中以及union是有意义的,因为无论如何你将一直传递它。

So I would recommend placing both in a struct : 所以我建议将它们放在一个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;
    };    
};

And then you can have separate functions for creating each subtype, for simpler instantiation: 然后,您可以使用单独的函数来创建每个子类型,以便更简单地实例化:

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

Meaning your main would do something like: 意思是你的main做的事情如下:

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

and just pass the var struct forward. 然后向前传递var结构。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM