管理几乎相同的数据结构用C

问题描述:

用下面的(简化的)数据定义:管理几乎相同的数据结构用C

#define DIM0 10 
#define DIM1 15 

typedef struct { 
    uint32_t var1: 
    ... 
    int8_t arrayVar1[DIM0]; 
} dataClass0; 

typedef struct { 
    uint32_t var1: 
    ... 
    int8_t arrayVar1[DIM1]; 
} dataClass1; 

在一个给定的点,我必须创建这些结构的阵列并处理它们。

除了数组(长度不同)之外,处理过程完全相同。现在它是这样的:

dataClass0 *data; 
data = (dataClass0 *) malloc(dimension * sizeof (dataClass0)); 
// Processing and filling structure 
data[i].var1 = <value> 
... 

现在我有复制给每个数据班组长相同的功能。使用这些数据结构时是否存在重复代码的方法?

注:

  • 只有纯C,没有C++;
  • 我无法更改数据定义(即不能在结构中使用int8_t *arrayVar1)。
  • 处理时,我收到要处理的数据类型(0表示class0,1表示class1,...)。
+0

这听起来像是其中一个宏可能是最合适的解决方案之一... – 2013-03-27 12:24:16

+3

您需要着名的** struct hack!** – 2013-03-27 12:24:32

+0

或者一个* flexible数组*,因为它自C99以来就被称为。 – WhozCraig 2013-03-27 12:26:46

typedef struct { 
    uint32_t var1: 
    ... 
    int8_t arrayVar[]; /* Declare as flexible array, allowed since C99 */ 
} dataClass; 

有类似的东西分配:

data1 = malloc(sizeof (dataCLass) + DIM1*sizeof ((dataClass*)NULL)->arrayVar[0]); 
data2 = malloc(sizeof (dataCLass) + DIM2*sizeof ((dataClass*)NULL)->arrayVar[0]); 
or define 
#define ALLOCDATA(dim) malloc(sizeof (dataCLass) + (dim)*sizeof ((dataClass*)NULL)->arrayVar[0]); 

定义

#define ELEMENT1(data, i) (dataClass*)(((char*)(data))+(i)*(DIM1+sizeof (dataCLass))) 
#define ELEMENT2(data, i) (dataClass*)(((char*)(data))+(i)*(DIM2+sizeof (dataCLass))) 

,或者如果你参数化的DIM

#define ELEMENT(data, i, dim) (dataClass*)(((char*)(data))+(i)*((dim)+sizeof (dataCLass))) 

享受

ELEMENT1(data1, i)->var1 = 1; 
ELEMENT1(data1, i)->arrayVar1[9] = 4; 


ELEMENT2(data2, i)->arrayVar1[14] = 4; 

ELEMENT(data1, i, DIM1)->var1 = 1; 
ELEMENT(data1, i, DIM1)->arrayVar1[9] = 4; 


ELEMENT(data2, i, DIM2)->arrayVar1[14] = 4; 

并不完美,但不是太怪异构建到无法使用。

编辑: 元素定义应改为

#define ELEMENT1(data, i) (dataClass*)(((char*)(data))+(i)*(DIM1*sizeof ((dataClass*)NULL)->arrayVar[0]+sizeof (dataCLass))) 
#define ELEMENT2(data, i) (dataClass*)(((char*)(data))+(i)*(DIM2*sizeof ((dataClass*)NULL)->arrayVar[0]+sizeof (dataCLass))) 

#define ELEMENT(data, i, dim) (dataClass*)(((char*)(data))+(i)*((dim)*sizeof ((dataClass*)NULL)->arrayVar[0]+sizeof (dataCLass))) 

这种变化,你arrayVar场可以是任何类型的,并不仅限于大小的元素1.

+1

在C数组中,长度为'0'是不允许的。你正在接受的是一个扩展。你想做的正式方法是使用'[]'而不是'[0]',它被称为灵活数组成员。 – 2013-03-27 12:52:17

+0

好,已编辑。不改变任何东西,但。 – 2013-03-27 12:54:18

+0

确定这个改变,只是正确和不正确的代码之间的区别。 – 2013-03-27 13:02:37

难道你不能只让阵列动态?所以你用malloc()创建你的结构,然后初始化一些成员来保存大小(并确保它以uint8_t *而不是实际的数组结尾,或使用VLA)?

+0

看来,OP已经解决了这个问题...... – 2013-03-27 12:34:21

+1

显然不是。 '(即不能在结构中使用int8_t * arrayVar1)。' – Mike 2013-03-27 12:39:09

+0

这是正确的,我不能使用动态数组。 – mcieec 2013-03-27 13:36:33

这取决于是否或者不想你最初用不同的值填充数组。否则,你可以有一个初始化两种类型的结构

#define STRUCTURE_INITIALIZER(VAR1, VAR2) { .var1 = (VAR1), .var2 = (VAR2) } 

的宏观和使用,作为

dataClass0 data = STRUCTURE_INITIALIZER(31, 42); 

您的阵列组件随后将永远是0初始化,无论大小。

要初始化你的东西的malloc ED阵列:

dataClass0 *data = malloc(dimension * sizeof (dataClass0)); 

// Processing and filling structure 
for (size_t i = 0; i < dimension; ++i) 
    data[i]= (dataClass0)STRUCTURE_INITIALIZER(43, i); 

BTW,宁愿正确初始化的变量,不投的malloc回报。