【问题标题】:How to qsort an array of struct如何对结构数组进行qsort
【发布时间】:2014-04-14 04:28:55
【问题描述】:

所以我的任务是抓取一个二进制文件,将其读入由结构组成的数组,然后根据结构中的数组对其进行排序。我坚持的部分是排序。我不确定我是否应该将它作为一个数组排序(因为二进制文件现在是一个数组)还是将它作为一个结构进行排序。下面是我的部分代码。

typedef struct {
    char FlightNumber[7];
    char OriginCode [5];
    char DestinationCode [5];
    int Date [];
} FLIGHT;

int main(){

FLIGHT FlightData [3000];
/*opens file, freads it into the array then closes*/

/*trying to sort it based on OriginCode*/
int compare (const FLIGHT *a, const FLIGHT *b) {
    FLIGHT *ia = (FLIGHT *)a;
    FLIGHT *ib = (FLIGHT *)b;

    return strcmp(ia->OriginCode, ib->OriginCode);}

qsort( FlightData, 3000, sizeof( FLIGHT ), compare);
/*to see if sorting worked...*/
for (i = 0; i < 100; i++){

    printf ("%i) %s, %s, %s\n", i, FlightData[i].FlightNumber, FlightData[i].OriginCode, FlightData[i].DestinationCode );
}
}

基本上我不知道如何编写比较。

【问题讨论】:

标签: c arrays sorting struct qsort


【解决方案1】:

注意Date 在这里的大小为零,因为您没有为它分配任何空间。取消引用它是未定义的行为。

qsort 比较函数必须有这种类型:

int compare(const void *a, const void *b)

只要您更改函数签名以匹配此比较器,您的比较器就应该可以工作。

【讨论】:

    【解决方案2】:

    首先,比较器函数应该有签名:

    int compare(const void *v1, const void *v2);
    

    接下来,将 void 指针转换为结构指针:

        const FLIGHT *ia = (FLIGHT *)v1;
        const FLIGHT *ib = (FLIGHT *)v2;
    

    接下来,您需要逐个元素地系统地比较事物:

        int rc;
    
        if ((rc = strcmp(ia->OriginCode, ib->OriginCode)) != 0)
            return rc;
        if ((rc = strcmp(ia->DestinationCode, ib->DestinationCode)) != 0)
            return rc;
        …
        return 0;  // Only if the two entries compare as identical
    

    这会按始发机场代码、目的地机场代码以及您可以决定的其他标准(航班号、日期)进行排序。我注意到您没有指定日期的存储方式。由于它是一个整数数组(显然是一个“灵活数组成员”),因此您可能以某种顺序分别拥有“年、月、日”。

    当你有一个灵活的数组成员时,你不应该定义一个数组的结构,因为你不能在灵活的数组成员中存储任何东西。您可以拥有一个指针数组,但您需要单独分配结构。 OTOH,您真的不需要可变大小的数组来描述日期。您应该使用固定大小的数组,甚至是时间戳来提供时间和日期。剩下的问题是在一天出发并在另一天到达的航班——过夜旅客和跨越国际日期变更线的航班。实际上,您可能需要一个出发时间和一个到达时间。

    另请参阅(当然还有许多其他内容):

    【讨论】:

    • 我想知道这一点,这让我没有看到我找到的大多数帮助,但是 char 和 int(无论是否为数组)的比较器会写成相同的吗?
    • 这取决于你的意思。如果您对int 的数组进行排序,那么您可能会使用int i1 = *(int *)v1; int i2 = *(int *)v2; if (i1 &lt; i2) return -1; else if (i1 &gt; i2) return +1; else return 0; 作为函数体。这些比较的重点是避免算术溢出(人们经常写return i1 - i2;,但如果有算术溢出的机会,一切都会崩溃)。有关这方面的更多信息,请参阅“如何对结构数组进行排序”。
    • 另外,对于整数,可以使用比较return (i1 &gt; i2) - (i1 &lt; i2); 如果i1 &gt; i2,则返回+1;如果i1 &lt; i2,则返回-1;否则,它返回 0。它可能会设法避免条件,这可以在流水线架构中产生影响。它也总是执行两次比较,所以它有统一的时间。
    【解决方案3】:

    参考以下链接详细了解qsort 链接:http://www.cplusplus.com/reference/cstdlib/qsort/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-07
      • 2017-04-19
      • 1970-01-01
      • 2014-05-21
      • 1970-01-01
      • 1970-01-01
      • 2021-08-02
      相关资源
      最近更新 更多