管理几乎相同的数据结构用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,...)。
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.
在C数组中,长度为'0'是不允许的。你正在接受的是一个扩展。你想做的正式方法是使用'[]'而不是'[0]',它被称为灵活数组成员。 – 2013-03-27 12:52:17
好,已编辑。不改变任何东西,但。 – 2013-03-27 12:54:18
确定这个改变,只是正确和不正确的代码之间的区别。 – 2013-03-27 13:02:37
这取决于是否或者不想你最初用不同的值填充数组。否则,你可以有一个初始化两种类型的结构
#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
回报。
这听起来像是其中一个宏可能是最合适的解决方案之一... – 2013-03-27 12:24:16
您需要着名的** struct hack!** – 2013-03-27 12:24:32
或者一个* flexible数组*,因为它自C99以来就被称为。 – WhozCraig 2013-03-27 12:26:46