是否有一个 C 函数,给定具有不同数据类型的结构数组,可以使用任何一种数据类型对数组进行排序
Posted
技术标签:
【中文标题】是否有一个 C 函数,给定具有不同数据类型的结构数组,可以使用任何一种数据类型对数组进行排序【英文标题】:Is there a C function which, given a struct array with different data types, can sort the array with any one of the data types 【发布时间】:2021-12-06 17:30:28 【问题描述】:我正在排序/搜索结构数组。
struct Substance
char name[NAME_SIZE]
int mass;
double halftime;
在提示用户选择结构的哪个成员进行排序后完成排序/搜索,即按名称、质量或中场时间。
有没有办法制作一个可以处理所有三种数据类型的通用函数,还是我必须为每种类型编写不同的函数?
我不想写几个函数的原因是每个函数中90%的代码都是一样的。
我特别苦恼于我必须为每次迭代获取我想要操作的成员,即substances[i].mass
来访问质量,并且对于结构的每个成员,这种语法显然必须不同。
我试图做一些预处理来避免这个问题:
switch(choice)
case '1':
memcpy(current, substances[i].name, NAME_SIZE);
break;
case '2':
sprintf(current, "%d", substances[i].mass);
break;
case '3':
sprintf(current, "%lf", substances[i].halftime);
但如果我想按mass
排序,我还必须在结构数组中转换所有其他物质的mass
。
我还考虑过首先将每个成员表示为相同的数据类型,然后在需要时进行转换,例如打印、写入文件等,但我不知道我会使用哪种数据类型。
一般用例是:
/*
Do you want to sort by (1) name, (2) mass or (3) halftime: 2
Sorted list by mass:
Name Mass Halftime
Zirconium 91 ...
Radon 220 ...
Radon 222 ...
Uranium 238 ...
*/
【问题讨论】:
您可以将qsort
(或您自己的排序函数)与三个不同的compar
函数一起使用。
@Silop 您可以使用 qsort 并且对于结构的每个数据成员,您需要编写一个单独的比较函数。
Glibc 提供了函数qsort_r()
,它接受一个额外的指针参数,该参数传递给比较函数,因此您可以编写一个比较函数,根据额外的参数决定对哪个数据成员进行排序。但是,这不再是可移植的 C。
【参考方案1】:
是的qsort()。示例:
给定结构:
struct Substance
char name[NAME_SIZE]
int mass;
double halftime;
;
假设数组定义为substances[N];//has been populated
,那么调用的例子可以是:
qsort(substances, N, sizeof (struct Substance), compareName);
qsort(substances, N, sizeof (struct Substance), compareMass);
qsort(substances, N, sizeof (struct Substance), compareHtime);
...在qsort()
中传递比较函数的形式是:
int compareName(const void *a, const void *b)
const struct Substance *ia = a;
const struct Substance *ib = b;
return strcmp(ia->name, ib->name);//returns -1, 0 1 per strcmp rules
int compareMass(const void *a, const void *b)
const struct Substance *ia = a;
const struct Substance *ib = b;
return ia->mass == ib->mass ? 0 :
ia->mass > ib->mass ? 1 : -1;
int compareHtime(const void *a, const void *b)
const struct Substance *ia = a;
const struct Substance *ib = b;
return fabs(ia->halftime - ib->halftime) < 0.00001 ? 0 :
(ia->halftime - ib->halftime) > 1 ? 1 : -1;
“有没有办法制作一个可以处理所有三种数据类型的通用函数,或者我必须为 每个?”
您可以创建一个使用您的switch()
的void 函数,并使用enum
。决定调用三个比较函数中的哪一个。例如:
enum
NAME,
MASS,
HALF,
TYPE_MAX
;
void sort(struct Substance *s, size_t size, int type)
switch(type)
case NAME;
qsort(s, size, sizeof (struct Substance), compareName);
break;
case
...
【讨论】:
最后两个函数的return
语句有错别字。 (ia->mass ib->mass )
缺少操作员。
他们还根据排序返回两个原始值之一,而不是负/0/正(通常为-1/0/1
)。
@kaylum - 编辑了最后两个函数。
@ShadowRanger - 感谢您的编辑。
不需要演员表。以上是关于是否有一个 C 函数,给定具有不同数据类型的结构数组,可以使用任何一种数据类型对数组进行排序的主要内容,如果未能解决你的问题,请参考以下文章