是否有一个 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-&gt;mass ib-&gt;mass ) 缺少操作员。 他们还根据排序返回两个原始值之一,而不是负/0/正(通常为-1/0/1)。 @kaylum - 编辑了最后两个函数。 @ShadowRanger - 感谢您的编辑。 不需要演员表。

以上是关于是否有一个 C 函数,给定具有不同数据类型的结构数组,可以使用任何一种数据类型对数组进行排序的主要内容,如果未能解决你的问题,请参考以下文章

c语言里面的结构体是啥意思

Java:将具有不同类型的参数传递给函数

将表值参数传递给具有不同字段数的存储过程

具有类私有成员和函数指针的继承结构

java中都有哪些数据结构

我可以验证给定的函数类型签名是不是具有潜在的实现吗?