说我有以下代码:
struct test* t1;
t1 = get_t(1);
...其中get_t
是:
struct test* get_t(int);
如何重构上面的代码并将其放入函数中?如下所示:
void r1(?* t, ?* (fn*)(int)) {
t = fn(1);
}
/* ... */
struct test* t1;
r1(t1, &get_t);
答案 0 :(得分:4)
我有两个想法:
[1]将void
指针传递给变量/对象,并在函数中输入它。
[2]建立所有数据类型的并集以及整数数据类型,该数据类型将标识union中哪个数据类型变量保存实际数据。将此联合作为值或void *
struct _unknown {
union {
int a;
float b;
char c;
double d;
} data;
int type;
} unknown;
.
.
.
if (unknown.type == FLOAT)
{
/* Process variable b */
}
else if (unknown.type == INT)
{
/* Process variable a */
}
.
.
.
像这样。
您可以将FLOAT
和INT
以及其他人哈希定义为唯一值。
或者只是
struct _unknown {
void *data;
int type;
} unknown;
.
.
.
if (unknown == FLOAT)
{
/* process (float *) data */
}
else if (unknown == INT)
{
/* process (int *) data */
}
else if (unknown == MY_DATA_TYPE)
{
/* process (my_data_type *) data */
/* where my_data_type could be a typedef, or struct */
}
答案 1 :(得分:3)
使用void *param
,指向任何内容的指针......在glib中常用gpointer
答案 2 :(得分:1)
如果你有gcc,你可以使用这个更安全的版本:
#define r1(varp,func) ({ \
typeof(**varp)* (*_func_)(int); \
typeof(**varp)* _varp_ = (varp); \
_func_ = (func); \
r1_((void**)(_varp_),(void*(*)(int))_func_); \
})
void r1_(void** varp,void*(*func)(int))
{
*varp = func(1);
}
请致电:
struct test* get_t(int);
struct test* t1;
r1(&t,get_t);
(你不需要在函数上使用&
,它们会像数组一样自动衰减到指针。这将检查t
是否为指针,get_t
是返回该指针类型的函数。 _varp_
在技术上是不必要的,但保持参数评估的顺序正确。
如果你没有gcc,你仍然可以这样做,但你必须明确提供类型:
#define r1(T,varp,func) do { \
T*(*_func_)(int); \
T* _varp_ = (varp); \
_func_ = (func); \
r1_((void**)(_varp_),(void*(*)(int))_func_); \
} while(0)
void r1_(void** varp,void*(*func)(int))
{
*varp = func(1);
}
请致电:
struct test* get_t(int);
struct test* t1;
r1(struct test*,&t,get_t);
不太安全,而且更加冗余,但仍然相当不错。