如何使用本机 qsort 对 C 中的 `int **` 数组进行排序

S. *_*rma 0 c sorting qsort

我一直找不到任何与此相关的问题,我想我想弄清楚这个问题有点疯狂。

\n\n

我有以下代码:

\n\n
#include <stdio.h>\n#include <stdlib.h>\n#include <errno.h>\n#include <time.h>\n\nint cmp_int(const void *a, const void *b)\n{\n  return * (int *)a - * (int *)b;\n}\n\nint main(int argc, char *argv[])\n{\n  int n = 10;\n  int **arr = calloc(n, sizeof(int *));\n  srand((unsigned int) time(NULL));\n  for (int i = n-1; i >= 0; i--) {\n    arr[i] = calloc(1, sizeof(int));\n    *(arr[i]) = rand() % 1000;\n  }\n  for (int i = 0; i < n; i++)\n    printf("%d ", *(arr[i]));\n  printf("\\n");\n  qsort(arr, 10, sizeof(void *), cmp_int);\n  for (int i = 0; i < n; i++)\n    printf("%d ", *(arr[i]));\n  printf("\\n");\n  free(arr);\n  return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是非常基本的,对吧?根据联机帮助页,第一个参数是指向基本元素的指针,第三个参数是大小。但是,我无法将数组作为排序结果。我仍然很困惑 qsort 的第一个和第三个参数应该是什么,因为我怀疑这就是错误所在。

\n\n

任何帮助表示赞赏。

\n\n

谢谢。

\n\n

编辑:我应该补充一点,这段代码显然没有进行错误检查,并且我试图用整数的双指针数组来测试 qsort,所以虽然是的,但我可以使用一个常规数组,但这不是这段代码的预期目的(它\xe2\x80\x99s 实际上是单独程序中更大段的一部分)。

\n

Gen*_*ene 5

你的程序让我头疼。您没有得到正确排序的原因是比较函数错误。需要得到return **(int **)a - **(int **)b;正确的结果。

然而,以这种方式解决问题是不值得的。至少列出一些问题的列表:

  • 如果您不使用argcand argv,则不要声明它们。
  • 调用中的强制转换srand是不必要的。
  • int通过减法进行比较是一个坏主意,因为它可能会溢出。
  • calloc应始终检查返回结果是否为空(内存不足)。
  • calloc根本不需要。使用可变长度数组。
  • 无需分配指向 int 的指针数组。只需分配一个整数数组即可。然后你的比较就按原样进行。
  • qsort调用使用硬常量 10 而不是n
  • 通过取消引用数组名称来给出元素大小不太容易出错。
  • 最后,您释放了“spine”数组,但没有释放整数元素。
  • 您应该提取一个函数来打印数组。

这是解决这些问题的版本。

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

int cmp_int(const void *va, const void *vb)
{
  int a = *(int *)va, b = *(int *) vb;
  return a < b ? -1 : a > b ? +1 : 0;
}

void print(int *a, int n) {
  for (int i = 0; i < n; ++i) printf("%d ", a[i]);
  printf("\n");
}

int main(void)
{
  int n = 10, a[n];
  srand(time(0));
  for (int i = 0; i < n; ++i) a[i] = rand() % 1000;
  print(a, n);
  qsort(a, n, sizeof a[0], cmp_int);
  print(a, n);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • @EsmaeelE:如果您的编译器在使用“int main(int argc, char **argv)”时没有抱怨未使用的变量,然后不使用“argc”或“argv”,那么您还没有足够的警告已启用。您需要说服编译器为您提供的一切帮助。 (2认同)