【问题标题】:Casting void* to a variable data type in C将 void* 转换为 C 中的变量数据类型
【发布时间】:2014-12-27 17:37:38
【问题描述】:

我尝试编写一个函数,在数据结构中找到 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.

你认为这可能吗?

【问题讨论】:

  • 这是使用void 指针的问题之一 - 您会丢失有关指针指向的数据类型的所有信息。
  • C 没有办法进行动态类型声明,所有类型都必须静态指定。您可以做的最好的事情是一个固定的数据类型列表,您可以使用if/then/else 或switch 进行处理。
  • 请参阅stackoverflow.com/questions/18577404/… 了解我所说的示例。

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


【解决方案1】:

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

【讨论】:

  • 我希望它适用于所有可能的类型。但没关系,这是不可能的。我找到了一种更好的方法来做我想做的事。
【解决方案2】:

我可以考虑将类型标识符字段添加到您的 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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 2019-06-11
    相关资源
    最近更新 更多