C:制作通用迭代函数?
C: Make generic iteration function?
我有一个结构体,它定义了一个结构体数组,每个结构体又包含几个数组。这些内部数组定义了我的 'datasets'.
在许多地方,我希望遍历所有数据集。为了避免 3 个嵌套循环,我遍历了数据集的总数,并使用一些 if 语句来跟踪我需要访问的数组。它看起来像这样:
int datasetCount = 0;
int defendedDatasetCount = 0;
int i;
Dataset *ds;
for (i = 0 ; i < totalDatasets ; i++)
{
// If we have passed the number of datasets in this group, move to the next group
if (datasetCount == (dg->nDatasets + dg->nDefDatasets))
{
dg++;
datasetCount = 0;
defendedDatasetCount = 0;
}
// If we have gone through all the (undefended) datasets, read from thte defended datasets
if (datasetCount >= dg->nDatasets)
{
ds = &(dg->defDatasets[defendedDatasetCount]);
defendedDatasetCount++;
}
else
{
ds = &(dg->datasets[datasetCount]);
}
其中 dg
是指向结构的指针,它只是一个结构数组和一个 size
计数器。
我发现自己在执行不同操作的几个函数中重复此样板代码以遍历数据集。
我正在努力想出这样的东西:
while (give_me_next_dataset(dg) == TRUE)
{
...
}
可能吗?
有可能,但提议的 API 不是很好。您将不得不将迭代状态放在某个地方,并且您不会为此留下任何空间。
我会提出这样的建议:
struct DgIter {
struct Dg *dg;
size_t index;
size_t dataSet;
};
那么你可以有这样的功能:
struct DgIter iter_start(struct Dg *dg)
{
const struct DgIter iter = { dg, 0, 0 };
return iter;
}
void * iter_next_dataset(struct DgIter *iter)
{
// check if there is a current dataset, else return NULL
// update fields in iter as necessary
}
我有一个结构体,它定义了一个结构体数组,每个结构体又包含几个数组。这些内部数组定义了我的 'datasets'.
在许多地方,我希望遍历所有数据集。为了避免 3 个嵌套循环,我遍历了数据集的总数,并使用一些 if 语句来跟踪我需要访问的数组。它看起来像这样:
int datasetCount = 0;
int defendedDatasetCount = 0;
int i;
Dataset *ds;
for (i = 0 ; i < totalDatasets ; i++)
{
// If we have passed the number of datasets in this group, move to the next group
if (datasetCount == (dg->nDatasets + dg->nDefDatasets))
{
dg++;
datasetCount = 0;
defendedDatasetCount = 0;
}
// If we have gone through all the (undefended) datasets, read from thte defended datasets
if (datasetCount >= dg->nDatasets)
{
ds = &(dg->defDatasets[defendedDatasetCount]);
defendedDatasetCount++;
}
else
{
ds = &(dg->datasets[datasetCount]);
}
其中 dg
是指向结构的指针,它只是一个结构数组和一个 size
计数器。
我发现自己在执行不同操作的几个函数中重复此样板代码以遍历数据集。
我正在努力想出这样的东西:
while (give_me_next_dataset(dg) == TRUE)
{
...
}
可能吗?
有可能,但提议的 API 不是很好。您将不得不将迭代状态放在某个地方,并且您不会为此留下任何空间。
我会提出这样的建议:
struct DgIter {
struct Dg *dg;
size_t index;
size_t dataSet;
};
那么你可以有这样的功能:
struct DgIter iter_start(struct Dg *dg)
{
const struct DgIter iter = { dg, 0, 0 };
return iter;
}
void * iter_next_dataset(struct DgIter *iter)
{
// check if there is a current dataset, else return NULL
// update fields in iter as necessary
}