简体   繁体   English

如何在C中对结构数组进行排序?

[英]How to sort an array of structs in C?

I have got an array of the following structs 我有以下结构的数组

typedef struct _my_data_ 
{
  unsigned int id;
  double latitude;
  double longitude;
  unsigned int content_len;
  char* name_dyn;
  char* descr_dyn;
} mydata;

and would like to sort it ascending by the ID . 并想按ID升序对其进行排序。 I read it is possible to sort arrays using the qsort function but I am not sure how to correctly use it when sorting structs. 我读过可以使用qsort函数对数组进行排序,但是我不确定在对结构进行排序时如何正确使用数组。

Any help would be appreciated. 任何帮助,将不胜感激。

You need a structure comparator function that matches the prototype of the function expected by qsort() , viz: 您需要一个结构比较器函数,该函数与qsort()期望的函数原型匹配,即:

int md_comparator(const void *v1, const void *v2)
{
    const mydata *p1 = (mydata *)v1;
    const mydata *p2 = (mydata *)v2;
    if (p1->id < p2->id)
        return -1;
    else if (p1->id > p2->id)
        return +1;
    else
        return 0;
}

If you ever get to a more complex sort criterion, this is still a good basis because you can add secondary criteria using the same skeleton: 如果您使用了更复杂的排序标准,那么这仍然是一个很好的基础,因为您可以使用相同的框架添加次要条件:

int md_comparator(const void *v1, const void *v2)
{
    const mydata *p1 = (mydata *)v1;
    const mydata *p2 = (mydata *)v2;
    if (p1->latitude < p2->latitude)
        return -1;
    else if (p1->latitude > p2->latitude)
        return +1;
    else if (p1->longitude < p2->longitude)
        return -1;
    else if (p1->longitude > p2->longitude)
        return +1;
    else
        return 0;
}

Clearly, this repeats for as many criteria as you need. 显然,可以根据需要重复执行许多条件。 If you need to call a function ( strcmp() ?) to compare values, call it once but assign the return to a local variable and use that twice: 如果您需要调用一个函数( strcmp() ?)比较值,请调用一次,但将返回值分配给局部变量并使用两次:

int md_comparator(const void *v1, const void *v2)
{
    const mydata *p1 = (mydata *)v1;
    const mydata *p2 = (mydata *)v2;
    int rc;
    if (p1->latitude < p2->latitude)
        return -1;
    else if (p1->latitude > p2->latitude)
        return +1;
    else if (p1->longitude < p2->longitude)
        return -1;
    else if (p1->longitude > p2->longitude)
        return +1;
    else if ((rc = strcmp(p1->name_dyn, p2->name_dyn)) < 0)
        return -1;
    else if (rc > 0)
        return +1;
    else
        return 0;
}

Also, this template works when data members are unsigned integers, and it avoids overflow problems when comparing signed integers. 同样,当数据成员为无符号整数时,此模板也可以使用,并且在比较有符号整数时避免了溢出问题。 Note that the short cut you might sometimes see, namely variations on: 请注意,您有时可能会看到快捷方式,即:

int md_comparator(const void *v1, const void *v2)   /* BAD */
{                                                   /* BAD */
    const mydata *p1 = (mydata *)v1;                /* BAD */
    const mydata *p2 = (mydata *)v2;                /* BAD */
    return(p1->id - p2->id);                        /* BAD */
}                                                   /* BAD */

is bad if id is unsigned (the difference of two unsigned integers is never negative), and subject to overflow if the integers are signed and of large magnitude and opposite signs. 如果id是无符号的(两个无符号整数的差永远不会为负),则是不好的;如果整数是有符号的且幅度较大且符号相反,则可能会溢出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM