是否有一个 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
我是sorting/searching一个结构数组。
struct Substance
{
char name[NAME_SIZE]
int mass;
double halftime;
}
sorting/searching 是在提示用户选择要排序的结构成员后完成的,即按名称、质量或中场休息时间。
有没有办法制作一个可以处理所有三种数据类型的通用函数,还是我必须为每种类型编写不同的函数?
之所以不想写几个函数,是因为每个函数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()。示例:
给定结构:
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;
}
"Is there a way to make a general function that can work with all of the three data types or do I have to write different functions for
each?"
您可以创建一个使用 switch()
并使用 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
...
我是sorting/searching一个结构数组。
struct Substance
{
char name[NAME_SIZE]
int mass;
double halftime;
}
sorting/searching 是在提示用户选择要排序的结构成员后完成的,即按名称、质量或中场休息时间。
有没有办法制作一个可以处理所有三种数据类型的通用函数,还是我必须为每种类型编写不同的函数?
之所以不想写几个函数,是因为每个函数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()。示例:
给定结构:
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;
}
"Is there a way to make a general function that can work with all of the three data types or do I have to write different functions for each?"
您可以创建一个使用 switch()
并使用 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
...