c语言 qsort 对结构体数组排序

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c语言 qsort 对结构体数组排序相关的知识,希望对你有一定的参考价值。

定义了结构体如下:
typedef struct tagMYDATA

char _buf1[10];

char _buf2[10];

MYDATA, *pMYDATA;

比较:
int cmp(const void* a, const void* b)

return strcmp((*(pMYDATA)a)._buf1, (*(pMYDATA)b)._buf1);

int main()

int _n = 10;

pMYDATA* _data = NULL;
_data = (pMYDATA*)malloc(sizeof(MYDATA)*_n);
//初始化动态数组
qsort(_data, _n, sizeof(_data[0]), cmp);

for(i=0;i<rowcount;i++)
printf("%s\n", _data[i]->_buf1);

return 0;



基本的代码就是这样,但是输出的时候是乱码,请各位看看是怎么回事

参考技术A ■可能的一个原因是compare 里给a、b赋值的时候,后面强制类型转换应为(struct record *)而非(record *)。
■可能另一个原因是你的源文件名后缀(DECVPP据此判断是C程序还是C++程序),如果是纯C的,就用.c;如果是C++的,用.cpp。
■还有可能是你没有包含必要的头文件?
我根据你的代码做了个简单的测试,在VC6下运行正常(由大到小按point排)。
#include <stdio.h>
#include <stdlib.h>
struct record

char name[35];
int point;
int match[3];
int goal[2];
;

int compare(const void *p1,const void *p2);
void input(struct record s[], int n);
void output(struct record s[], int n);

int main()

struct record team[35];
int teams = 35;
input(team, 5);
qsort(team,teams,sizeof(team[0]),compare);
output(team, 5);
return 0;


int compare(const void *p1,const void *p2)

struct record *a= (struct record *)p1;
struct record *b= (struct record *)p2;
int result=0;
if(a->point > b->point)
return -1;
else if(a->point< b->point)
return 1;
else
return 0;



void output(struct record s[], int n)

int i=0;
while(i<n)

printf("%d ",s[i].point);
i++;

return;


void input(struct record s[], int n)


int i=0;
while(i<n)

scanf("%d",&(s[i].point));
i++;

return;

是否可以解决您的问题?追问

代码是纯c的,编译通过能运行,不排序输出数组每个元素的字符串正常。

以上您的代码没有任何问题。问题出在我这样分配不对,修改后正确了。

非常感谢这么晚了,帮我解答问题。

本回答被提问者采纳

qsort函数实现对任意数据的排序

学会使用qsort函数排序

qsort介绍

qsort函数是一个库函数,它的作用是对数据进行排序,思想是:快速排序!

因为是库函数,所以在使用的时候需要引头文件:<stdlib.h>/<search.h>

我们可以通过以下的方式使用qsort函数:qsort( (void *)argv, (size_t)argc, sizeof( char * ), compare );
参数解释:
(void *)argv:你想要从哪个数组/结构体的哪个元素开始排序就将它的地址作为实参。

(size_t)argc:你想要排序的元素个数。

sizeof(char*):排序的元素大小;

compare:是一个函数指针,指向的函数是比较元素大小的,因为不同的数据的比较方法是不同的,所以在创建qsort函数的时候将比较方法抽离出来,需要我们编写。

假如我要使用qsort排序一个数组的全部元素,那么我在引用qsort的时候应该这么写:

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

int main()

	int arr[] = 9,5,4,8,3,1,7,6,10,2 ;
	int sz = sizeof(arr) / sizeof(arr[0]);//计算数组每个元素的大小
	qsort(arr, sz, sizeof(arr[0]), compare);

	return 0;



如果我只想排序5到7共6个元素的时候那我该这么写:

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

int main()

	int arr[] = 9,5,4,8,3,1,7,6,10,2 ;
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr+1, 6, sizeof(arr[0]), compare);

	return 0;



compare函数介绍

compare函数是qsort排序的核心

compare函数的定义形式: compare( const void* elem1, const void* elem2 )。

看到这里是不是感觉怪怪的?再引用compare函数的时候并没有参数啊,怎么这里有两个指针呢?我在接触到qsort的时候也有这样的疑问,于是我找到了qsort的函数原型:

static void __cdecl shortsort(char *lo, char *hi, size_t width,  
                                                          int (__cdecl *comp)(const void *, const void *));


static void __cdecl swap(char *p, char *q, size_t width);

可以看到compare确实是有两个指针的,至于elem1和elem2的地址是如何传进去的,博主也不太懂呢,需要去研究源码,但是我们知道它是把 (void *)argv的地址和 (void *)argv+1的地址传了过去,并且每次调用玩都会对地址进行加一操作,一直到(size_t)argc的地址为止,知道这些就足够我们使用qsort函数了。

从这张图片我们可以看到,当elem1指向的元素大于elem2指向的元素时compare函数会返回一个正值等于的时候会返回0小于的时候会返回负值,这对没深入理解compare函数的我们来说不知道返回正值、0、负值意味着什么,我们只需要记住这样的写法未来排序完成是升序的就行,如果想要降序加个负号或者交换两个指针的位置就可以了。

这里我想说一下void*指针,这个指针是一个万能指针,它可以接收任何类型的元素的地址,但是它也有美中不足的地方,那就是无法对这个指针进行任何的运算操作,像什么++,–,*等都是不行的,因为它没有类型,在进行这些操作时无法知道它该访问几个字节的内存,自然是无法进行操作。

不同的数据类型相应的比较函数定义

对数组元素为数字的:

int  compare(const void *e1,const void *e2)


	return  *(int*)e1 - *(int*)e2;//结果要返回正,0,负,那我干脆让它们相减。


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

int main()

	int arr[] = 9,5,4,8,3,1,7,6,10,2 ;
	int sz = sizeof(arr) / sizeof(arr[0]);//计算元素个数
	qsort(arr, sz, sizeof(arr[0]), compare);
	int a = 0;
	for (a = 0; a < sz; a++)
	
		printf("%d\\n", arr[a]);
	
	return 0;


在return的时候将e1和e2指针进行了强制类型转换,因为void的指针是不能解引用的,又因为数组元素是int,所以转为int。
如果是小数如下,double也一样:

int  compare(const void *e1,const void *e2)


	return  (int)(*(float*)e1 - *(float*)e2);//将指针强制转换为float*,将计算结果转为int


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

int main()

	float arr[] = 9.22,9.21,8.99,8.21,0,8.89,10.2,7.8,6.3,10.1,2.1 ;
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), compare);
	int a = 0;
	for (a = 0; a < sz; a++)
	
		printf("%f\\n", arr[a]);
	
	return 0;


数组元素为字符时比较函数定义:

在c语言中,字符和整数是相通的,所以它们的比较函数差不多:

int  compare(const void *e1,const void *e2)


	return  (int)(*(char*)e1 - *(char*)e2);



#include<stdlib.h>

int main()

	char arr[] = 'e','f','c','a','b';
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), compare);
	int a = 0;
	for (a = 0; a < sz; a++)
	
		printf("%c\\n", arr[a]);
	
	return 0;

结构体数据比较函数定义:

结构体其实和数组一样:

struct stu//创建结构体变量

	char name[20] ;
	int age;
;
int compare(const void*e1, const void *e2)

	return  strcmp((*(((struct stu*)e1)->name) , *(((struct stu*)e2)->name)));//将指针强制转换为结构体指针



int main()

	struct stu s1[3] =    "zhangsan" ,  20  ,   "lisi" ,  10  ,   "abo" ,  15   ;
	//s1是一个数组,数组有3个元素,每个元素都是一个结构体。
	int sz = sizeof(s1) / sizeof(s1[0]);
	qsort(s1, sz, sizeof(s1[0]), compare);
	int a = 0;
	for (a = 0; a < sz; a++)
	
		printf("%s\\n", (s1+a)->name);//打印结构体
	
	return 0;


``

博主不才,如有错误请及时指出,如果有想深入了解qsort函数的朋友 点击链接  [qsort函数源码分析](https://blog.csdn.net/nuptxxp/article/details/6961030) 相信会找到你想要的。

加油csdn的小伙伴,让我们一起努力,向大厂前进!!!

以上是关于c语言 qsort 对结构体数组排序的主要内容,如果未能解决你的问题,请参考以下文章

4.19 使用qsort对结构体数组进行排序,实现对结构的体一级排序和二级排序,进一步了解qsort的原理

在c中怎样用qsort对结构体数组进行多级排序

Qsort 结构体数组

C语言结构体数组排序

求教一个问题,如何用sort对结构体数组排序

C语言,结构体快排