将void *转换为C中的可变数据类型

时间:2014-12-27 17:37:38

标签: c parameters casting type-conversion custom-data-type

我尝试编写一个函数,在数据结构中找到 void指针 。该函数必须将void*强制转换为任何类型的结构。

假设我写了一个结构,我以 void指针 的形式存储在我的数据结构中。然后我调用该函数,该函数打印所有存储数据元素的信息。 要做到这一点,函数必须知道它应该转换为哪种类型。

所以我的问题是:是否有可能以某种方式为函数提供所需的信息?

示例代码:

typedef struct{
    int a, b
} teststruct;


void DSOut(datastructure* ds, datatypeinfo dt){
    //...
    //search for data in ds
    //...
    //if data is found cast it to the type defined in dt
    //and print out the a and b fields
}


int main(){
    datastructure* ds = DSCreate(4, 3);  //can hold any type of data,
                                         //but should hold just one at a time
                                         //4 and 3 are just example parameters
    teststruct ts;
    ts.a = 4;
    ts.b = 10;

    teststruct ts2;
    ts2.a = 6;
    ts2.b = 12;

    //Add the teststructs to the data-structure
    DSAdd(2, 2, ts);     //the numbers are just for example
    DSAdd(4, 1, ts2);


    datatypeinfo  dt = teststruct;   //stores the type teststruct for DSOut
    DSOut(ds, dt);   //function, that prints information of all added teststructs

    return 0;
}

在此示例中DSOut(x,y)应打印以下内容:

- on position 2, 2 is an element which holds following data: 4, 10.
- on position 4, 1 is an element which holds following data: 6, 12.

你认为这是可能的吗?

2 个答案:

答案 0 :(得分:1)

类型不能作为C中的参数传递,因此对问题的简短回答是"不能,它不能完成",至少在一般情况下不是这样。你可以传递一些东西,它可以让你识别一组有限的类型,然后硬编码如何处理每种类型(我想到一个大的switch语句)。由于您没有指定datatypeinfo的外观,因此不清楚您的期望是多么普遍。

答案 1 :(得分:1)

我可以考虑在struct中添加类型标识符字段并检查它的值以决定如何打印它,并使用函数初始化结构以处理type字段

enum Types {
    Point3D,
    Point2D
};

struct Base {
    enum Types type;
};

struct Point3D {
    enum Types type;
    int x;
    int y;
    int z;
};

struct Point2D {
    enum Types type;
    int u;
    int v;
};

void print(void *data)
{
    switch (((struct Base *)data)->type)
    {
    case Point2D:
        {
            struct Point2D *point;

            point = (struct Point2D *)data;
            printf("2D: %d, %d\n", point->u, point->v);
        }
        break;
    case Point3D:
        {
            struct Point3D *point;

            point = (struct Point3D *)data;
            printf("3D: %d, %d, %d\n", point->x, point->y, point->z);
        }
        break;
    }
}

void initialized2dPoint(struct Point2D *const point, int u, int v)
{
    if (point == NULL)
        return;
    point->type = Point2D;

    point->u = u;
    point->v = v;
}

void initialized3dPoint(struct Point3D *const point, int x, int y, int z)
{
    if (point == NULL)
        return;
    point->type = Point3D;

    point->x = x;
    point->y = y;
    point->z = z;
}

int main(void)
{
    struct Point2D point2d;
    struct Point3D point3d;

    initialized2dPoint(&point2d, 1, 2);
    initialized3dPoint(&point3d, 3, 4, 5);

    print(&point2d);
    print(&point3d);

    return 0;
}