我有一个带有union的结构,如下所示
typedef struct {
Type_e type;
union {
char m_char;
int m_int;
// more types. over 27 types with special types
} my_data;
} Data_t;
此结构用于开发算法,包括函数/方法内的奇异值分解(SVD)。但是,每次我需要访问union的元素时,我都要使用switch(超过10个switch()将用于SVD)。基于我有限的理解,在每个时刻,所有工会成员都拥有相同的价值。我可以使用char成员并将其转换为不同类型吗?例如:
Data_t lData;
// initialize lData with some values
int x = (int)(lData.my_data.m_char).
以及如何为指针投射?
即使使用了铸造,我仍然需要在某些情况下使用开关。有没有办法避免使用开关?我尝试使用不同的struct格式(如Declare generic variable type中所述),看起来使用union更具可读性。以前,我没想到结束了:(
在前一篇文章中提到了这个例子,它有一个类似的开关
的例子void vector(Data_t *vec, UInt32_t start_element, UInt32_t end_element)
{
UInt32_t i;
// check *vec is not null
if (!vec)
{
// Write error
}
Data_t x;
for (i =start_element; i <= end_element; i++)
{
switch (vec[i].type)
{
case UINT32: x.my_data.m_int = vec[i].my_data.m_int; break;
// more possible cases
default:
break;
}
}
}
答案 0 :(得分:2)
由于我刚加入SO,我还没有声明添加评论。所以将其添加为答案:
从我看到的情况来看,即使你想要输入它,正如你在问题中所说的那样,那么在那个位置你就会知道它是哪种类型(int或char)。在这种情况下,您可以直接访问m_int
,因此无需切换或转换。
所以你要么遵循这种使用联合的方法,要么使用other answer
中提到的(void *)答案 1 :(得分:1)
我认为没有任何聪明的方式可以访问工会成员,这比访问工会成员的官方,正常,便携方式更快。</ p>
听起来你正在内循环中访问联合。如果您有类似
的内容for(i = 0; i < ni; i++) {
for(j = 0; j < nj; j++) {
for(k = 0; k < nk; k++) {
switch(type) {
case T_CHAR:
u[i][j][k].m_char = f(v[i][j][k].m_char);
break;
case T_INT:
u[i][j][k].m_int = g(v[i][j][k].m_int);
break;
如果显示type
的值没有变化,那么是的,您花了很多时间执行switch
语句总计{{ 1}}次而不是你最想要的那一次。
加快速度的直接方法是将ni*nj*nk
移到循环之外:
switch
当然,这里的一个巨大缺点是你已经为每种类型复制了N次循环遍历代码。因此,面临的挑战是找到一种最小化工作的方法,特别是如果代码可能会发生变化,并且您不想在所有N个位置进行更改。
如果您遇到这种情况,我们可以更具体地说明如何以更清洁的方式实现高效的代码。 (例如,我曾经使用过一些预处理器技巧来复制循环代码N次。)
答案 2 :(得分:0)
首先,请记住,char通常是8位,而int通常是32.(“通常”,因为可移植性是一种痛苦)。
但是如果你有足够大的数据类型来保存你想要的任何种类,是的,你可以在每次类型重要的交互中将变量转换为所需的类型。对于数学繁重的图书馆而言,这可能是很多。在每次交互时,你都需要一个switch语句来将它转换为正确的类型,所以你并没有真正获得任何东西。
联盟的众多开关可能是一种痛苦,但它可能是最好的方式。它可以避免为所有10种数据类型复制所有这些代码。
谷歌在C中进行泛型编程。有些人尝试过使用函数指针和宏的替代方案。