C - 混合 Qsort 与结构(字符串和 double )

标签 c arrays loops struct qsort

我有一个几乎完整的代码,需要对一些东西进行 Qsort,首先我有整数数组、 float 数组,然后我有带有 char 和 double 组合数组的结构。需要以某种方式对它们进行 qsort,但我被卡住了。

这是我的代码,我对整数和 float 排序没有问题,但我无法完成结构排序。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LEN 20

typedef struct product
{
    double price;
    char name[LEN];
} product;


int ComparFuncInt(const void *x, const void *y);
int ConparFuncFloat(const void *x, const void *y);
int ComparFuncStructName(const void *x, const void *y);
int ComparFuncStructPrice(const void *x, const void *y);
/* void PrintIntegerArray(int *numbers, int len);
void PrintFloatArray(float *numbers, int len);
void PrintStructArray(product *items, int len);
*/
int main(void)
{
    unsigned option;

    /* initialized variables to be used with functions */
    int numArr1[] = {15, 25, 3, 19, 22, 17, -54, 0, 9};
    float numArr2[] = {76.40f, 11.2f, 235.4f, 76.50f, 341.6f};
    product prices[] = {{0.75f, "Milk"}, {0.99f, "Yogurt"}, {3.19f, "Cucumber"},
                        {1.09f, "Orange"}, {0.80f, "Bread"}, {0.99f, "Juice"}};
    int numCount = sizeof(numArr1) / sizeof(int);
    float floatCount = sizeof(numArr2) / sizeof(float);
    double doubleCount = sizeof(struct product) / sizeof(double);
    char charCount = sizeof(struct product) / sizeof(char);


    while (1)
    {
        printf("\n\nSelect your action!\n\n");
        printf("1. Sort integers (numArr1)\n");
        printf("2. Sort decimals (numArr2)\n");
        printf("3. Sort structures by price\n");
        printf("4. Sort structures by name\n");
        printf("0. Exit\n");
        scanf("%u", &option);
        switch (option)
        {
            case 1:
                qsort(numArr1, (size_t)numCount, sizeof(int), ComparFuncInt);
                for (int i = 0; i < numCount; printf("%3d", numArr1[i]), i++);
                break;
            case 2:
                qsort(numArr2, (size_t)floatCount, sizeof(float), ConparFuncFloat);
                for (int j = 0; j < floatCount; printf("%.2f ", numArr2[j]), j++);
                break;
            case 3:
                qsort(prices, (size_t)doubleCount, sizeof(double), ComparFuncStructPrice);
                for (int k = 0; k < doubleCount; printf("%.2f ", prices[k].price), k++);
                break;
            case 4:
                qsort(prices, (size_t)charCount, sizeof(char), ComparFuncStructName);
                for (int l = 0; l < charCount; printf("%s", prices[l].name), l++);
                break;
            case 0:
                exit(1);
                break;
            default:
                printf("Only selections from 1 to 4 and 0 are accepted\n");
        }
    }
    return EXIT_SUCCESS;
}


int ComparFuncInt(const void *x, const void *y){
    if(* (int*)x > *(int*)y) return 1;
    else if(* (int*)x < *(int*)y) return -1;
    else return 0;
}
int ConparFuncFloat(const void *x, const void *y){
    if(* (float *)x > *(float *)y) return 1;
    else if(* (float *)x < *(float *)y) return -1;
    else return 0;
}
int ComparFuncStructName(const void *x, const void *y){
    const char *pa = *(const char**)x;
    const char *pb = *(const char**)y;
    return strcmp(pa,pb);
}
int ComparFuncStructPrice(const void *x, const void *y){
    if(* (float *)x > *(float *)y) return 1;
    else if(* (float *)x < *(float *)y) return -1;
    else return 0;
}

我想这样做,当用户选择 3 时,它会按价格对产品下的 PRICES 数组进行排序,如果用户选择 4,它应该按名称排序,在这两种情况下,它都应该输出价格和名称,只是差异按排序方式。

最佳答案

在比较函数中,指针(在您的例子中是xy)是指向数组元素的指针。如果数组是 int,则它是指向 int 的指针(即 int *)。如果它是结构数组,则它们是指向结构 的指针(例如 product *)。

要访问结构的成员,您当然需要使用正确的结构指针访问,例如箭头运算符 ->

如果将指针保存在适当的变量中也会更容易,这样您就不必一直进行所有转换。事实上,如果您想将传递的数据用作指针而不是值,则根本不需要强制转换,因为 void * 可以隐式转换为几乎任何其他指针类型(函数指针除外)。

因此对于您的结构比较功能,您可以这样做

int ComparFuncStructName(const void *x, const void *y){
    const product *a = x;
    const product *b = y;

    return strcmp(a->name, b->name);
}

当然,由于您正在对结构数组进行排序,数组的元素大小就是结构的大小,因此您也需要修复它:

qsort(prices, charCount, sizeof prices[0], ComparFuncStructName);

哦,你对结构中元素数量的计算也是错误的。公式为 sizeof array/sizeof array[0]总是。无论数组的类型或其元素如何。 sizeof 的结果总是 size_t,因此您也应该将它用作所有 sizeof 操作的类型。

所以你需要做

size_t charCount = sizeof prices / sizeof prices[0];

关于一个不相关且更具风格的注释:不要将 printf 调用与 for 循环的增量表达式结合使用。这将使代码更难阅读、理解、遵循和(最重要的)维护。

将所有语句放在循环体中:

for (int l = 0; l < charCount; l++)
    printf("%s", prices[l].name);

您也不需要为循环使用不同的迭代变量。它们对于自己范围内的循环而言是本地的,因此您可以为所有循环重用 i

关于C - 混合 Qsort 与结构(字符串和 double ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53431348/

相关文章:

C指针上的指针: unused variable

c++ - 进入循环时出现段错误

php - 在PHP中将字符串数组转换为整数数组

c++ - C++可变参数模板参数方法传递给没有可变参数的方法

Java io 流关闭错误

c# - 异常处理 - catch 子句中的异常?

c - 作为参数发送到后台子进程的空闲内存

c - 在 C 中使用数组 [100] 时出现运行时错误

ios - 为多个数据创建和自定义一个 UIButton

C 结构和指针混淆