使用qsort按不同的变量对结构指针进行排序

时间:2012-03-23 21:08:32

标签: c pointers struct qsort

我试图在指向结构的指针的上下文中理解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最大到最小,使用struct

中的total

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

谢谢

2 个答案:

答案 0 :(得分:3)

您只需要定义两个不同的比较函数。每个比较函数应该有两个指向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);

答案 1 :(得分: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;
}