在任何情况下,您都需要为每个数据成员编写一个单独的函数来对数组进行排序,因为在函数中您需要比较具体数据成员的值。
但是,您可以编写一个通用函数,为调用 qsort 提供所需的比较函数。
这是一个演示程序。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
char* name;
int age;
float wage;
} employee;
int cmp_by_name( const void *a, const void *b )
{
const employee *first = a;
const employee *second = b;
return strcmp( first->name, second->name );
}
int cmp_by_age( const void *a, const void *b )
{
const employee *first = a;
const employee *second = b;
return ( second->age < first->age ) - ( first->age < second->age );
}
int cmp_by_wage( const void *a, const void *b )
{
const employee *first = a;
const employee *second = b;
return ( second->wage < first->wage ) - ( first->wage < second->wage );
}
enum SortBy { ByName, ByAge, ByWage };
int ( *select( enum SortBy sort_by ) )( const void *, const void * )
{
int ( *cmp[] )( const void *, const void * ) =
{
cmp_by_name, cmp_by_age, cmp_by_wage
};
switch ( sort_by )
{
default:
case ByName:
return cmp[ByName];
case ByAge:
return cmp[ByAge];
case ByWage:
return cmp[ByWage];
}
}
int main(void)
{
enum { N = 3 };
employee e[N] =
{
{ "Tom", 18, 3500.0f },
{ "Bob", 26, 4500.0f },
{ "Jim", 28, 4000.0f }
};
for ( size_t i = 0; i < N; i++ )
{
printf( "%s, %d, %f\n", e[i].name, e[i].age, e[i].wage );
}
putchar( '\n' );
qsort( e, N, sizeof( employee ), select( ByName ) );
for ( size_t i = 0; i < N; i++ )
{
printf( "%s, %d, %f\n", e[i].name, e[i].age, e[i].wage );
}
putchar( '\n' );
qsort( e, N, sizeof( employee ), select( ByAge ) );
for ( size_t i = 0; i < N; i++ )
{
printf( "%s, %d, %f\n", e[i].name, e[i].age, e[i].wage );
}
putchar( '\n' );
qsort( e, N, sizeof( employee ), select( ByWage ) );
for ( size_t i = 0; i < N; i++ )
{
printf( "%s, %d, %f\n", e[i].name, e[i].age, e[i].wage );
}
putchar( '\n' );
return 0;
}
程序输出是
Tom, 18, 3500.000000
Bob, 26, 4500.000000
Jim, 28, 4000.000000
Bob, 26, 4500.000000
Jim, 28, 4000.000000
Tom, 18, 3500.000000
Tom, 18, 3500.000000
Bob, 26, 4500.000000
Jim, 28, 4000.000000
Tom, 18, 3500.000000
Jim, 28, 4000.000000
Bob, 26, 4500.000000