未知字段的代码重用

时间:2012-10-21 04:30:23

标签: c

如果我有一个排序算法,我想按结构的某个字段排序。我基本上正在寻找一个参数(在这种情况下为sortBy)能够确定是否比较fieldOne,或者是fieldTwo - 而不是不断检查要使用的正确字段的可能性。

void func(SomeType *arr, int length, int sortBy) {
    int i;
    for(int i = 0; i < length, i++) {
        if(sortBy == 1) {
            doSomethingTo(arr[i].fieldOne);
        }
        else if(sortBy == 2) {
            doSomethingTo(arr[i].fieldTwo);
        }
        // etc
    }
}

2 个答案:

答案 0 :(得分:1)

是。有一个解决方案:

void sampleDoSomethingFunction(SomeType *arg) {
}

void func(SomeType *arr, int length, void (*doSomething)(SomeType *arg)) {
    int i;
    for(int i = 0; i < length, i++) {
        doSomething(&arr[i]);
    }
}

然后你像这样调用func:

    func(arr,length, sampleDosomethingFunction);

答案 1 :(得分:1)

您可以观察标准C qsort()的作用。它使用比较器函数对任何类型的任何数组进行排序:

void qsort(void *base, size_t nel, size_t width,
           int (*compar)(const void *v1, const void *v2));

如果v1应该在v2之前排序,比较器函数返回负值,如果它应该排序,则返回正值,如果在此排序标准下值相等,则返回零。注意,有必要比较两个值;将一个值与自己的肚脐进行比较是不够的。

在您的示例中,您似乎正在对固定类型进行排序。您可以使用qsort(),或者您可以借用比较器类型的想法,并根据您的类别进行调整:

void func(SomeType *arr, int length, int (*comparator)(const SomeType *v1, const SomeType *v2))
{
    ...
    int cmp = comparator(&arr[i], &arr[j]);
    ...
}

您的比较器可能是:

static int compare_fieldOne(const SomeType *v1, const SomeType *v2)
{
    if (v1->fieldOne < v2->fieldOne)
        return -1;
    else if (v1->fieldOne > v2->fieldOne)
        return +1;
    return 0;
}

如果您需要进行更多比较,可以在else if子句后添加额外的测试对,将相等的情况留到最后。