如果变量的类型必须在C中确定为运行时但变量名是固定的并且给定,是否有任何方法可以重用涉及变量的代码?
其实我在询问runtime determine type for C++的C对应情况。
如果可能,请举一些例子。
答案 0 :(得分:7)
C语言没有面向对象的功能,这使得在C ++中询问对象的运行时类型变得有意义。
您通常通过在void*
之间进行转换来实现C中的通用性。示例:the C function qsort。
如果你的问题是关于在运行时确定void*
指针指向的实际类型,那是不可能的。大多数编译器都根本不存储这些信息。
答案 1 :(得分:1)
一种标准技术是提供快速类型信息变量作为参数 并打开它,并通过引用传递所有数据。在函数内部,我们使用显式转换来恢复该值。 void *类型未被编译器取消选中,因此危险是发送一个未被函数处理的类型(分段错误,数据损坏或未知行为结果)。 首先设置所需类型的枚举:
在这种情况下,我使用约定TYPE_FUNCTION来表示返回类型的函数。
enum指令从0开始选择连续的整数, 或者您可以为每个枚举分配自己的int值。
typedef enum D_types {
ANINT, // don't use actual system type names
AFLOAT,
ADOUBLE,
ASTRING,
MY_STRUCT=100,
MY_STRUCT2=200
VOID_FUNCTION=1000,
INT_FUNCTION = 2000,
STRUCT_FUNCTION=3000
} DATATYPE;
/* an f_int is a function pointer to a function */
typedef int (*f_int)(int, void* );
在您的函数定义中,您可以通过引用和类型发送数据 并在使用前将其转换为正确的类型:
int myfunction ( DATATYPE dt, void* data, )
{
int an_int = 0;
int * ip; // typed pointers for casting of the void pointer data
double * dp;
char * sp;
struct My_struct * msp;
struct My_struct_2 * ms2p;
f_int fp;
...
switch (dt){
case ANINT:
ip = (int*) data; // only pointers can be assigned void pointer values.
int i = *ip // dereference of typed pointer, no dereferencing void pointers.
...
break;
case ADOUBLE:
dp = (double*) data;
double d = *dp;
...
break;
case ASTRING:
char * s = strdup( (char*) data); // cast to char pointer allowed (pointer->pointer)
...
break;
case MY_STRUCT:
msp = ( struct My_Struct *) data;
char* ms_name = msp->name; // if my_struct has a name string ...
float dollarvalue = msp->dvalue;
...
case INT_FUNCTION:
fp = (f_int)data;
an_int = fp( ANINT, 5);
}
return an_int;
}
正如你可能猜到的,这是在烟花工厂玩火柴, 并不鼓励作为一种持续的做法。
在你的代码中你可以这样称呼它:double pi =3.14159;
int g = myfunction( ADOUBLE, &pi ); // pass by reference, not value
int j = myfunction (ASTRING , "HEY NOW" ); //C strings pass by ref normally
f_int myfunc = myfunction; // a function pointer (ref to the functions address )
int r = myfunction ( INT_FUNCTION, myfunc ); /* function as a parameter ... */
除了一次性功能 建议使用varargs函数 http://www.eskimo.com/~scs/cclass/int/sx11b.html