#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[i] = ch;
if (i == 0)
word[i] = 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那一行,在那一行就会出错崩溃
qsort 函数在C语言中用于对数组进行排序。
它需要以下几个参数:
- 数组的指针
- 数组中元素的数量
- 每个元素的大小的比较函数
在鱼油的代码中, q sort 用于排序的对象不是一个数组,而是一个链表。
这是造成崩溃的原因。
链表和数组在内存中的组织方式完全不同。
数组是连续内存块,而链表由一系列使用指针链接的节点组成,这些节点可以分散在内存的不同位置。
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 。
|