孤不冷cing 发表于 2024-2-19 13:10:59

库函数qsort使用出错

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

#define MAX_LEN 20

struct word {
      char *word;
      struct word *next;
};

void *malloc_word(void);
char *read_word(void);
int compare_word(const void *p, const void *q);

int main(void)
{
      struct word *first = NULL;
      for (int i = 0; first == NULL && i < 3; i++)
                first = malloc_word();

      int num_words = 0;
      char *word;
      struct word *p, *last;
      p = first;
      do {
                printf("Enter a word: ");
                word = read_word();
                p->word = malloc(MAX_LEN);
                if (p->word == NULL)
                        exit -1;
                strcpy(p->word, word);
                num_words++;
                p->next = malloc_word();
                if (p->next != NULL) {
                        last = p;
                        p = p->next;
                }
                else
                        return 1;
      }while (strcmp(word, "\n"));
      free(p);
      p = last;
      p->next = NULL;
      num_words--;

      qsort(first, num_words, sizeof(struct word), compare_word);

      printf("In sorted order: ");
      p = first;
      for (int i = 0; i < num_words; i++)
      {
                printf("%s ", p->word);
                p = p->next;
      }
      putchar('\n');

      return 0;
}

void *malloc_word(void)
{
      struct word *p;
      p = malloc(sizeof(struct word));
      if (p != NULL)
                return p;
      return NULL;
}

char *read_word(void)
{
      char *word;
      word = malloc(MAX_LEN);
      if (word == NULL)
                exit -1;
      int ch;
      int i;
      for (i = 0, ch = getchar(); ch != '\n'; ch = getchar(), i++)
                word = ch;

      if (i == 0)
                word = ch;

      return word;
}

int compare_word(const void *p, const void *q)
{
//      return strcmp(((struct word *) p)->word, ((struct word *) q)->word);
      return ((struct word *) p)->word - ((struct word *) q)->word;
}

只要加上qsort那一行,在那一行就会出错崩溃

不二如是 发表于 2024-2-19 13:11:00

qsort 函数在C语言中用于对数组进行排序。

它需要以下几个参数:

[*]数组的指针
[*]数组中元素的数量
[*]每个元素的大小的比较函数


在鱼油的代码中, qsort 用于排序的对象不是一个数组,而是一个链表。

这是造成崩溃的原因。

链表和数组在内存中的组织方式完全不同。

数组是连续内存块,而链表由一系列使用指针链接的节点组成,这些节点可以分散在内存的不同位置。

qsort 期望一个连续的内存块来访问和交换元素,这与链表的结构不兼容。

此外, compare_word 函数中的比较逻辑也是不正确的。

strcmp 函数是正确比较两个字符串的方法,您注释掉的那行应该是正确的。

当前未注释的行试图直接比较指针值,而不是它们所指向的字符串内容。

要修复这个问题,您需要实现一个专门针对链表排序的算法,例如归并排序。

如果想要使用 qsort ,则必须首先将链表的内容复制到一个数组中,对数组进行排序,然后再将排序后的内容回写到链表中。



如果决定改用数组并使用 qsort ,您的 compare_word 函数应该如下所示:

int compare_word(const void *p, const void *q)
{
    const struct word *wp = p;
    const struct word *wq = q;
    return strcmp(wp->word, wq->word);
}
如果希望继续使用链表,那么需要使用不同的方法来排序,而不是 qsort 。

FishC 发表于 2024-2-19 13:11:08

这是因为你在比较函数`compare_word`中使用了错误的指针减法操作`((struct word *) p)->word - ((struct word *) q)->word`。指针减法操作只适用于两个指针指向同一个数组或同一个数据结构的不同成员时才能得到正确的结果,而不是用于比较字符串的字典顺序。

正确的做法是使用`strcmp`函数来比较字符串的字典顺序,就像你注释掉的那一行代码一样:

return strcmp(((struct word *) p)->word, ((struct word *) q)->word);

这样就可以正常地使用`qsort`函数进行排序了。希望能帮到你!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: 库函数qsort使用出错