当前位置: 首页 > 知识库问答 >
问题:

C中的QSORT函数

缑文栋
2023-03-14

在下面的代码中,一旦我删除了比较字符串的注释部分,我就会出现seg 11错误。我无法理解为什么!其余代码运行良好。感谢任何帮助!

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

int compare_scores_desc(const void* scorea, const void* scoreb){
int a = *(int*)scorea;
int b = *(int*)scoreb;
return a-b;
}

int compare_names(const void* namea, const void* nameb){
char** a = *(char**)namea;
char** b = *(char**)nameb;
return strcmp(*a,*b);
}

int main(int argc, char* argv[]){
int scores[7] = {456,234,65,563,67,19,100};
int i;
qsort(scores,7,sizeof(int),compare_scores_desc);
puts("\nThese are the scores in order : \n");
for(i=0;i<7;i++)
    printf("%i\n",scores[i]);
char *names[] = {"Krishna","Rama","Bhishma","Arjuna"};
/*qsort(names,4,sizeof(char*),compare_names);*/
puts("------------------");
puts("The names in order are : \n");
for(i=0;i<4;i++)
    printf("%s\n",names[i]);
return 0;
}

共有2个答案

聂永怡
2023-03-14

问题出在字符串比较函数中,下面可能是解决问题的最简单方法:

int compare_names(const void* namea, const void* nameb){
char* a = *(char**)namea;
char* b = *(char**)nameb;
return strcmp(a,b);
}

namea和nameb参数是字符串向量的指针。您理解这一点,这就是为什么您使用char类型。

然而,在函数中需要做的就是从该数组中检索指针。这些指针已经是字符串了。您不必再次取消引用它们;只需将它们传递给strcmp。

您的原始代码违反了约束,需要进行诊断。这本该告诉你的:

/* originally */
char** a = *(char**)namea; /* error: initialization from incompatible type */

您正在取消引用char**,这会产生char*,但您再次将其存储在char**中并再次取消引用,从而错误地将字符数据视为指针。

公西俊民
2023-03-14

在compare_names()中,您在强制转换后不适当地取消了对参数的引用。局部变量的类型是typechar**,但您将参数强制转换为char**,并且取消引用会导致char*

nameanameb是指向在main()中声明的数组元素的指针。这意味着,它们的类型实际上是指向char的指针。当您取消引用这些参数,但将其分配给一个字符时,您会导致局部变量将字符视为一个字符(您的编译器应该发出有关此问题的诊断警告)。现在,您获取一个指针值,它是一个字符*,当您将其传递给strcmp()时,将其解引用。这导致程序将字符串的sizeof(char*)字节视为strcmp()函数的指针值。由于由重新解释为指针值的可打印字符组成的4或8(或任何大小)字节很少生成有效指针,当strcmp()尝试使用这些指针时,就会出现分段错误。

一种可能的修复方法是在初始化局部变量时不取消引用。但是,参数是const val*,因此如果您将局部变量声明为指向const类型的指针,则可以完全避免强制转换:

int compare_names(const void* namea, const void* nameb){
char* const * a = namea;
char* const * b = nameb;
return strcmp(*a,*b);
}

请注意,如果a-b导致有符号整数溢出,则您的compare\u scores\u desc()实现将失败。例如,如果a是INT\u MAX,而b是-1。您应该修复您的实现,使其适用于所有情况。

int compare_scores_desc(const void* scorea, const void* scoreb){
const int *a = scorea;
const int *b = scoreb;
return (*a > *b) - (*a < *b);
}

 类似资料:
  • qsort(利用快速排序法排列数组) 相关函数 bsearch 表头文件 #include<stdlib.h> 定义函数 void qsort(void * base,size_t nmemb,size_t size,int ( * compar)(const void *, const void *)); 函数说明 参数base指向欲排序的数组开头地址,参数nmemb代表数组中的元素数量,每一元

  • qsort 利用快速排序法排列数组 相关函数 bsearch 表头文件 #include<stdlib.h> 定义函数 void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); 函数说明 参数base指向欲排序的数组开头地址,参数nmemb代

  • 这个问题是由打字错误或无法再复制的问题引起的。虽然这里可能有类似的问题,但这一问题的解决方式不太可能帮助未来的读者。 我试图使用qsort()对结构中的价格进行排序。排序后,结构中的一个元素(test)变为0。你能告诉我为什么以及如何解决它吗? 谢谢 输出为: 排序前订单id=0价格=4测试=2订单id=1价格=9测试=3订单id=2价格=5测试=0订单id=3价格=2测试=8订单id=4价格=8

  • 本文向大家介绍C / C ++中的mbsrtowcs()函数,包括了C / C ++中的mbsrtowcs()函数的使用技巧和注意事项,需要的朋友参考一下 在本文中,我们将讨论C ++ STL中std::mbsrtowcs()函数的工作,语法和示例。 什么是std::mbsrtowcs()? std::mbsrtowcs()函数是C ++ STL中的内置函数,在<cwchar>头文件中定义。表示将

  • 本文向大家介绍C / C ++中的putwchar()函数,包括了C / C ++中的putwchar()函数的使用技巧和注意事项,需要的朋友参考一下 在本文中,我们将讨论C ++ STL中putwchar()函数的工作,语法和示例。 什么是putwchar()? putwchar()函数是C ++ STL中的内置函数,在<cwchar>头文件中定义。putwchar()函数用于在标准输出设备上写

  • 我一直找不到任何关于这个的问题,我想我想弄清楚这个有点疯狂。 我有以下代码: 这是超级基本的,对吧?根据手册页,第一个参数是指向基本元素的指针,第三个参数是大小。但是,我无法将数组作为排序结果。我仍然很困惑qort的第一个和第三个参数应该是什么,因为我怀疑这就是故障所在。 感谢您的帮助。 谢谢 编辑:我应该补充一点,这段代码显然没有错误检查,而且我试图使用双指针整数数组测试qort,所以虽然是的,