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;
基本的代码就是这样,但是输出的时候是乱码,请各位看看是怎么回事
■可能另一个原因是你的源文件名后缀(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 对结构体数组排序的主要内容,如果未能解决你的问题,请参考以下文章