2015-07-10 202 views
4

我想在C中声明一个泛型变量类型(我不能C++),我在脑海中有以下选项。声明泛型变量类型

选项1

typedef struct 
{ 
    void *value; 
    ElementType_e type; 
} Data_t; 

选项2

typedef struct { 
    ElementType_e type; 
    union { 
     int a; 
     float b; 
     char c; 
    } my_union; 
} my_struct; 

其中ElementType_e是保存所有可能类型的变量的枚举(例如INT,炭,无符号整型,等等。)。我有点倾向于选项1,因为我不相信与开关相比,选角会增加额外的计算时间,对吧?

我只是想知道哪种类型更有用?我知道选项1将需要每次使用/访问时进行投射。是否有任何可能的问题可能发生与铸造(尤其是在不同的平台上运行/编译代码,例如32位和16位微)

虽然option2需要开关()做任何操作(例如添加,。 ..)。

以下链接解释了选项2更好(从可读性的角度来看),但我主要关注代码大小和计算成本。 Generic data type in C [ void * ]

回答

4

是有可能与铸造发生任何可能的问题

不,你不想投,因为没有必要从/到终场void分配时(投用C )。

我只是想知道哪种类型是比较有用?

两个做的,所以它依赖,如

  • 1是懒惰的(因为它是少打字,和几个不同的变量名记住)。
  • 2是谨慎的(因为它的类型保存,而不是选择1,其中“真实”的类型信息丢失,所以你甚至不能在ElementType_e指定类型的变量的地址)。

参考一comment

关于业绩我想到了这两种方法的区别并不是很大(如果实现三立),因为这两个选项需要从分配给/ condtional statments(例外这里有指针变量,对于选项1,没有条件分配的情况下)。

+0

你需要在void指针上进行算术运算时进行类型转换,对吧?你假设编译器(/运行时)知道指针设置为什么类型的对象,并执行操作,这是不正确的。 当你说第二个选项是警告,它增加了更多的计算时间? –

+0

@ rasred2004:“*你假设编译器(/ run-time)知道指针的类型是什么对象*”不,我不知道。我假定在应用任何操作之前,'void'指针的值被赋给了一个指向'ElementType_e'描述的类型的指针的实例。 – alk

+0

请看我更新的答案。 @ rasred2004 – alk

2

我建议使用联合。事实上,我用一个自己在类似的情况:

union sockaddr_u { 
    struct sockaddr_storage ss; 
    struct sockaddr_in sin; 
    struct sockaddr_in6 sin6; 
}; 

我在插座代码中使用这个工会在那里我可以用IPv4或IPv6地址来工作。在这种特殊情况下,“类型”字段实际上是每个内部结构中的第一个字段(ss.ss_family,sin.sin_family和​​)。

+0

这是很好的例子,你有没有你比较的结果从使用工会与其他的选择吗? –

+0

我做这个联盟时,我没有考虑过使用其他选项。我更喜欢这种方式,因为我不需要担心额外的内存分配,并且因为我可以轻松地将指向此联合的指针传递给任何需要'struct sockaddr'或相关结构的函数。它还利用了类型系统来验证你是否传递了你期望的东西,而你没有用'void *'得到它。 – dbush

1

我认为这个问题不是很好,因为程序员可以定义无限的数据类型。例如,考虑以下顺序:

typedef char S0_t; 
typedef struct { S0_t x; } S1_t; 
typedef struct { S1_t x; } S2_t; 
typedef struct { S2_t x; } S3_t; 

,很明显,这是可能的,从而为我们要定义为许多新类型无限期地遵循。
所以,没有一种直接的方式来处理这种可能性。另一方面,由于指针具有更灵活的特性,因此可以决定只使用指针类型来定义泛型类型。
因此,您的项目中使用的类型将只能是指针。
这样,大概就像下面的定义很简单的可以工作:

typedef void* generic_t;