如何知道C中未知类型变量的数据类型?

时间:2013-10-29 14:12:31

标签: c gcc c99

#include<stdio.h>
void fun(void *x)
{
    //what is the data type of 'x', since I could have passed float instead of 
    //  int so first I have to check datatype of this and then proceed further.
}
int main()
{
     int n=10;
     fun(&n);
}

你可以看到我们不知道&#39; x&#39;在函数fun()中,如何在不使用(传递)函数参数中的任何其他信息的情况下找出它?

5 个答案:

答案 0 :(得分:4)

C11有type-generic expressions来帮助您解决此问题。你可以做这样的例子:

#define myFunction(X) _Generic((X), \
    int *:   myFunctionInt,         \
    float *: myFunctionFloat,       \
    default: myFunctionInt          \
    )(X)

void myFunctionInt(int *x);
void myFunctionFloat(float *x);

然后按照你的方式打电话:

int n = 10;
myFunction(&n);

或:

float n = 10.0f;
myFunction(&n);

您将需要实现单独的目标函数,但您可以在那里执行指针魔术并传递给公共处理程序,例如。

答案 1 :(得分:2)

C没有运行时类型信息。当你传递一个指针时,你传递一个裸指针 - 一个内存地址。

如果您使用指针void但需要知道类型,那么您必须传递一些其他信息。否则,您可以为不同类型创建不同的函数,例如期望foo的{​​{1}},期望int的{​​{1}}等等。

答案 2 :(得分:2)

当您转换为void *时,您无法知道类型。使用void指针时必须小心,因为您可以将其强制转换为任何类型。这是有一个无效指针的目的。

答案 3 :(得分:2)

C不允许获取void*传递的变量类型。你可以做到的唯一事情是你自己编写一种面向对象的代码。

可能是这样的:

typedef struct generic_type_s 
{
    void* data;
    void  (*f)(void* data);
} generic_type_t;

void f_int(void* _data)
{
    int* data = (int*)_data;
    // Do something
}

int main()
{
   int data1 = 10;
   // Generic variable initialization
   generic_type_t gv;
   gv.data = &data1;
   gv.f = f_int;

   // Calling an appropriate function
   gv.f(gv.data);

   return 0;
}

答案 4 :(得分:0)

这样做的方法是使用标记的联合:

typedef enum {
    // will default to TypeUnitialized if unspecified in structure initializer
    TypeUninitialized = 0,
    TypeFloat = 1,
    TypeInt
} type_t;

typedef struct {
    type_t type;
    union {
        int u_int;
        float u_float;
    };
} gen_val_t;

void fun(gen_val_t v)
{
    switch (v.type) {
    case TypeFloat:
        // process float
        break;
    case TypeInt:
        // process int
        break;
    default:
        // error
        break;
    }
}

int main(int argc, char **argv)
{
    gen_val_t ov = { .type = TypeFloat,
                     .u_float = 3.45 };
    fun(ov);
}