Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中,哪种方法更适合创建类型不可知结构?_C_Types_Generic Programming - Fatal编程技术网

在C中,哪种方法更适合创建类型不可知结构?

在C中,哪种方法更适合创建类型不可知结构?,c,types,generic-programming,C,Types,Generic Programming,我想写一些通用结构。本质上,我需要的是C++模板,但是由于我在C中编写,所以模板是不需要考虑的。目前我正在考虑两种方法来实现我想要的 方法1:使用预处理器。像这样: #define DEFINE_PAIR(T) typedef struct Pair_##T{ \ T x; \ T y; \ } Pair_##T DEFINE_PAIR(i

我想写一些通用结构。本质上,我需要的是C++模板,但是由于我在C中编写,所以模板是不需要考虑的。目前我正在考虑两种方法来实现我想要的

方法1:使用预处理器。像这样:

#define DEFINE_PAIR(T) typedef struct Pair_##T{ \
                           T x; \
                           T y; \
                        } Pair_##T

DEFINE_PAIR(int);

int main(){
   Pair_int p;
   return 0;
}
一个明显的缺点是,在使用类型之前必须调用宏。可能还有更多的缺点,我希望你能指出

方法2:只需使用void指针,如下所示:

typedef struct Pair{
   void* x;
   void* y;
} Pair;
显然,这种方法不是类型安全的(我可以很容易地将一对字符串传递给一个需要一对双精度的函数),而且这种方法使执行释放的代码变得更加混乱

我想听听你对此的想法。两种方法中哪一种更好/更差?为什么?有没有其他方法可以用来用C编写泛型结构


谢谢。

如果您只打算使用基本数据类型,那么您原来基于宏的解决方案就足够漂亮了。但是,当您开始存储指向下面具有复杂结构的不透明数据类型的指针对时,这些指针将用于在函数之间传递指针,例如:

complex_structure_type *object = complex_structure_type_init();
complex_structure_type_set_title(object, "Whatever");
complex_structure_type_free(object);
那你必须

typedef complex_structure_type *complex_structure_type_ptr; 
为了

DEFINE_PAIR(complex_structure_type_ptr);
所以你可以

Pair_complex_structure_type_ptr p;
然后

p.x = object;
但这只是多一点点的工作,所以如果你觉得它对你有用,那就去做吧。您甚至可以将自己的预处理器放在一起,通过代码,提取任何类似Pair\u whatever的内容,然后为C预处理器添加DEFINE\u Pair(whatever)。不管怎么说,你在这里提出的想法绝对不错

就个人而言,我只会使用void指针,而忽略强类型安全性。C语言与其他语言没有相同类型的安全机制,你给自己更多的机会忘记一些东西,你会意外地产生更多的bug


祝你好运现在,这确实为您的构建添加了另一个步骤,并使您的构建依赖于另一个toll(除非您想用c编写自己的生成器…),但它可以提供您希望的灵活性和类型安全性。

这几乎是一样的,但它更灵活:

#define PAIR_T(TYPE) \
    struct { \
        TYPE x; \
        TYPE y; \
    }


typedef PAIR_T(int) int_pair;
typedef PAIR_T(const char *) string_pair;

int main(void)
{
    int_pair p = {1, 1};
    string_pair sp = {"a", "b"};
}

有关我曾经考虑过的相关但不完全相同的安排所导致的问题,请参阅+1问一个有趣的问题。你想做什么?没有一个包罗万象的最佳解决方案。我正在写一个处理图形的程序。我想让我的图形算法可重用。图形节点可以有一些附加信息,这就是为什么我想在节点的结构中保留一个任意类型的附加成员。您可以将您的
#define
,以及对某些常见类型的宏的调用,放入一个标头中,这样您就不必经常使用宏。C不太喜欢泛型编程。你会因为问我而恨我,但是你有没有理由不想使用C++?