我有一个几乎完整的代码,需要对一些东西进行 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,它应该按名称排序,在这两种情况下,它都应该输出价格和名称,只是差异按排序方式。
最佳答案
在比较函数中,指针(在您的例子中是x
和y
)是指向数组元素的指针。如果数组是 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/