【问题标题】:using a qsort to sort struct pointers by different variables使用 qsort 按不同变量对结构指针进行排序
【发布时间】:2012-04-08 10:39:59
【问题描述】:

我试图在指向结构的指针的上下文中理解 c 库 qsort。 这是我想要操作的现有代码:

结构:

#define MAX_NAME 20
#define NUM_MONTHS 12

typedef struct EMP {
    char name[MAX_NAME+1];
    int monthSales[NUM_MONTHS];
    int total;
} Emp;

数据的全局初始化及其大小:

Emp *data;//where all entries are kept
int empSize;

我已经构建了 2 个 Emp 指针数组,我想以不同的顺序引用数据:

Emp *nameArray[empSize];//an array of pointers to point to entries alphabetically
Emp *salesArray[empSize]; //an array of pointers to pointing to entries by sales

在它们被相同分配后,我想使用 qsort 以不同方式排列它们。 nameArray 按字母顺序,使用结构中的名称和 salesArray 从大到小,使用结构中的总数

比较方法和 qsort 参数应该是什么样的?

谢谢

【问题讨论】:

  • 这是作业吗?这看起来像是我在教育工作时可能提出的问题。
  • 你的代码是什么样的,它试图对其中一个数组进行排序?您是否从Emp data[empSize]; 数组开始,以便更容易理解它?我将从结构数组开始,让它工作,然后使用指针数组。然后编写第二个比较函数,并使用第二个指针数组。

标签: c pointers struct qsort


【解决方案1】:

按名称排序的示例:

#include <stdio.h>
#include <stdlib.h>
#define MAX_NAME 20
#define NUM_MONTHS 12

typedef struct EMP {
  char name[MAX_NAME + 1];
  int monthSales[NUM_MONTHS];
  int total;
} Emp;

int compareName(const void * a, const void * b)
{
  return (strcmp(((Emp*)a)->name, ((Emp*)b)->name));
}

int main()
{
  Emp *data;
  int empSize = 100;
  qsort(data, empSize, sizeof(Emp), compareName);
  // qsort(data, empSize, sizeof(Emp), compareSales);
  return 0;
}

【讨论】:

  • 你为什么使用sizeof(int)作为qsort()的第三个参数?
  • @PlatinumAzure, size: Size in bytes of each element in the array
  • 从技术上讲,在您的示例中,元素是 Emps(甚至不是指向它们的指针),但在 OP 的示例中,它们是 Emp *s。这些不保证与sizeof(int) 的大小相同,尤其是在 64 位系统上。此外,无论如何只使用sizeof(*data) 会更安全。这样一来,它就更加通用且面向未来。
【解决方案2】:

您只需要定义两个不同的比较函数。每个比较函数都应该接受两个指向 void 的指针(在这种情况下,您会将它们强制转换为 Emp ** 类型),然后如果第一个条目小于、等于或分别大于第二个。

对于基于总数的排序,您可以简单地从第一个中减去第二个total。如果第一个总数小于第二个总数,则结果为负数,而当第一个总数大于第二个总数时,则相反。当它们相等时,返回零。

int compareByTotal(const void *first, const void *second)
{
    int firstTotal = (*(Emp **)first)->total;
    int secondTotal = (*(Emp **)second)->total;

    return firstTotal - secondTotal;
}

第二个,因为是字符串比较,可以返回strcmp的值(遵循相同的返回值约定):

int compareByName(const void *first, const void *second)
{
    const char *firstName = (*(Emp **)first)->name;
    const char *secondName = (*(Emp **)second)->name;

    return strcmp(firstName, secondName);
}

然后你可以调用 qsort 并传入这些函数名:

/* given: */
Emp *nameArray[empSize];//an array of pointers to point to entries alphabetically
Emp *salesArray[empSize]; //an array of pointers to pointing to entries by sales

/* use: */
qsort(nameArray, empSize, sizeof(*nameArray), &compareByName);
qsort(salesArray, empSize, sizeof(*salesArray), &compareByTotal);

【讨论】:

    猜你喜欢
    • 2014-07-04
    • 2021-08-02
    • 2019-05-25
    • 1970-01-01
    • 2015-12-13
    • 2016-11-29
    • 2012-05-13
    • 2021-05-08
    相关资源
    最近更新 更多