如何在C中按给定成员对结构数组排序

如何在C中按给定成员对结构数组排序,c,arrays,sorting,struct,C,Arrays,Sorting,Struct,我有一个这样的结构: struct Car { int weight; int price; int speed; etc..} 我想写一个函数来对这种结构的数组进行排序 void sortCars(struct Car table[], int tableSize, ?structMemberParameter?) { struct Car temp; int swapped; for (int i = 0; i < tableS

我有一个这样的结构:

struct Car {
    int weight;
    int price;
    int speed;
    etc..}
我想写一个函数来对这种结构的数组进行排序

void sortCars(struct Car table[], int tableSize, ?structMemberParameter?)
{
    struct Car temp;
    int swapped;
    for (int i = 0; i < tableSize; i++)
    {
        swapped = 0;
        for (int j = 0; j < tableSize - 1; j++) {
            if (table[j].?structMemberParameter? > table[j + 1].?structMemberParameter?) {
                temp = table[j + 1];
                table[j + 1] = table[j];
                table[j] = temp;
                swapped = 1;
            }           
        }
        if (swapped == 0) {
            break;
        }
    }
}
void sortCars(struct Car table[],int tableSize,?structMemberParameter?)
{
结构车温度;
int交换;
for(int i=0;i表[j+1]。?structMemberParameter?){
温度=表[j+1];
表[j+1]=表[j];
表[j]=温度;
交换=1;
}           
}
如果(交换==0){
打破
}
}
}

我应该把什么作为“.structMemberParameter?”

编写一个比较函数,比较两个结构中的成员,并使用
qsort()
。您可以在手册中看到示例

这是问题标题的答案,你的问题的答案是你不需要传递成员,但是比较函数就像
qsort()
一样

因此,
if
语句变为

if (compare(&table[j], &table[j + 1]) > 0) ...
以及函数签名

typedef int (*cmpfn_type)(const struct Car *const, const struct Car *const);
void sortCars(struct Car table[], int tableSize, cmpfn_type compare);
因此,您可以有多个比较函数,例如,假设您希望按价格进行比较,那么合适的函数是

int compare_by_price(const struct Car *const A, const struct Car *const B)
{
    return (int) (A->price - B->price);
}
不过,你应该注意类型转换

这种方法的好处是,您可以轻松地重写比较函数,以使用
qsort()
库函数

注意:在评论中回答您的评论/问题时,您还可以使用枚举器,如

enum CarProperties {
    Speed, Price // ... AND SO ON
};
然后是一个排序函数,如

void sort_car_array(struct Car *const array,
        size_t size, enum CarProperties sort_property);
这里有一个
switch
语句来选择适当的回调以传递给一个泛型排序,比如说,
generic\u car\u array\u sort()
如上所述,甚至直接传递给
qsort()
,这将是一个更好的解决方案


如果您打算为
struct-Car
结构提供一个API,您可以这样做,我认为这是一个非常优雅的解决方案。我还建议将结构设置为不透明,只允许调用方通过函数设置/获取值

size\u t
by
offset of
正如您所描述的问题,没有解决方案。如果你放松你强加的约束,就会有解决办法。一种是使用独立的比较器,如iharob所述。另一种方法是编写宏而不是函数,缺点是这样一个宏不是特别安全的,不正确的使用会给编译器带来非常混乱的错误消息。我会坚持使用单独的比较器。我可以为每个成员编写比较器,但我可以编写始终有效的通用排序函数吗,sortCars(struct,Size,speed),sortCars(struct,Size,price)等等。。?在不需要新的比较器的情况下,所有成员都可以是int型的,所以所有的比较器都是相同的,只是在成员名上有所不同。@ PayWe DyMoSky:您可以考虑一个“通用比较器”函数,但是您可能需要使用偏移量(通过<代码>偏移量< <代码>宏> <代码> <代码> >数据的长度和类型,因为您可能有一些字符串和一组整数(可能还有一些浮点数,例如燃油消耗量或燃油箱的大小),而在一个函数中干净地处理所有这些内容是相当精细的。@PawełDymowski如果您想让同一类型的所有成员都可以通过在运行时计算的选择器访问,请使用数组<代码>枚举汽车财产{速度,价格,…,NumProperties};结构Car{int属性[NumProperties];}