函数概述

qsort 为quick sort的简写,意为快速排序,主要用于对各种数组的排序,在头文件stdlib.h中。

因为数组的元素可能是任何类型的,甚至是结构或者联合,所以必须高数函数qsort如何确定两个数组元素哪一个“更小”,这就需要我们给出比较的规则,即什么算大,什么算小。

通过编写比较函数可以为函数qsort提供这些信息。当给定两个指向数组元素的指针p和q时,比较函数必须返回一个整数。如果*p小于*q,那么返回的数为负数;如果*p等于*q,那么返回0.如果*p大于*q,返回正数。

函数原型

void qsort(void *base,size_t nmemb,size_t size,int (*compar)(const void *,const void *))

函数描述

函数的形式参数从左到右分别为:

指向要排序数组的第一个元素的指针base(如果只是要对数组的一段区域进行排序,那么要是base指向这段区域的第一个元素。)在一般情况下,base就是数组的名字;

nmemb是要排序元素的数量(不一定是数组中元素的数量);

size是每个数组元素的大小,用字节来衡量;

compar为指向比较函数的指针。

比较函数的实现

比较函数的实现是qsort函数能否正确实现的重点。

编写比较函数并没有想象中的那么容易。函数qsort要求它的形式参数类型为void *,但我们不能通过void *型的指针访问数组的成员;我们需要指向要比较元素的类型的指针。为了解决这个问题,我们将在比较函数内部把p与q赋给相应对应类型的指针变量。由于常量指针不能赋值给变量。所以在声明对应指针变量时应该加上const关键字。

下面是一个比较整型数组的比较函数的例子。

    int compare(const void *p, const void *q)
{
const int *p1 = p;
const int *q1 = q;
if (*p1 < *q1)
return -1;
else if (*p1 == *q1)
return 0;
else
return 1;
}

当然除了把用const指针变量的方法,还可以使用强制类型转换的方式来达到这个目的。

    int compare(const void *p,const void *q)
{
if(*(int *)p<*(int *)q)
return -1;
else if(*(int *)p==*(int *)q)
return 0;
else
return 1;
}

还可以进一步精简

    int compare(const void *p,const void *q)
{
return *(int *)p-*(int *)q;
}

需要注意的点:比较元素是指针的比较函数的实现。

如果待比较的元素是指针(虽然我们一般不会比较指针的大小,但是我们经常需要对指针代表的空间比较大小,比如比较一个字符串数组的大小,每个字符串都由一个指针代表),那么比较函数的实现就比较麻烦了。

首先我们需要明确的是,比较函数中的两个指针必须要指向需要比较的两个元素。如果这两个元素是指针而不是一个实体,那么这两个指针应该是指向指针的指针。

这里我们以一个比较字符串的比较函数举例:

    int compare(const void *p,const void *q)
{
return strcmp(*(char **)p,*(char **)q);
}

9/25补充

昨天刷题的时候发现一个和qsort有关的坑。

如果在写cmp函数时使用return *(int *)p-*(int *)q;简写,而比较函数比较后返回的是一个int值,这种写法在比较元素是整型的时候没有什么问题,但是如果比较的元素是double时,那么返回值可能和实际值不一样了,例如如果两个实型数据分别是1.1和1.0,返回的结果会变成0,这时函数qsort会把它们当成相同的元素。

此时正确的写法应该是return *(double *)p>*(double *)q?1:0;

参考博客:qsort函数排序各种类型的数据。

【C/C++】qsort函数的使用方法和细节的更多相关文章

  1. qsort函数以及sort函数使用方法

     sort函数的使用方法 做ACM题的时候,排序是一种常常要用到的操作. 假设每次都自己写个冒泡之类的O(n^2)排序,不但程序easy超时,并且浪费宝贵的比赛时间,还非常有可能写错. STL里面 ...

  2. qsort函数、sort函数【转】

    http://blog.163.com/yuhua_kui/blog/static/9679964420142195442766/ 先说明一下:qsort和sort,只能对连续内存的数据进行排序,像链 ...

  3. C中的qsort函数和C++中的sort函数的理解与使用

    一.qsort()函数 原型:_CRTIMP void __cdecl qsort (void*, size_t, size_t,int (*)(const void*, const void*)); ...

  4. qsort函数用法【转】

    qsort函数用法 qsort 功 能: 使用快速排序例程进行排序  用 法: void qsort(void *base, int nelem, int width, int (*fcmp)(con ...

  5. qsort函数用法

    qsort函数用法   qsort 功 能: 使用快速排序例程进行排序 用 法: void qsort(void *base, int nelem, int width, int (*fcmp)(co ...

  6. qsort函数用法(转)

    qsort函数用法   qsort 功 能: 使用快速排序例程进行排序  用 法: void qsort(void *base, int nelem, int width, int (*fcmp)(c ...

  7. C语言qsort函数用法

    qsort函数简介 排序方法有很多种:选择排序,冒泡排序,归并排序,快速排序等. 看名字都知道快速排序是目前公认的一种比较好的排序算法.因为他速度很快,所以系统也在库里实现这个算法,便于我们的使用. ...

  8. 关于c语言中qsort函数的一点心得

    今天写c时无意间用到了排序,便想着使用c语言标准库中提供的排序函数,即qsort函数(c++stl中提供了sort函数用于排序),首先是介绍qsort函数的一些基本用法(以下内容转自: http:// ...

  9. qsort函数、sort函数 (精心整理篇)

    先说明一下qsort和sort,只能对连续内存的数据进行排序,像链表这样的结构是无法排序的. 首先说一下, qsort qsort(基本快速排序的方法,每次把数组分成两部分和中间的一个划分值,而对于有 ...

随机推荐

  1. Powered by .NET Core 进展0819:高速开车车况汇报

    继续以流水账的方式向大家汇报,自从上周六上午将 .net core 版博客站点从 windows 部署切换到 linux 上的 docker-compose 部署后,到目前一直在线. Linux 上没 ...

  2. idea2019.2安装指南

    先去官网下载idea官网地址 下载UItimate版本点击 DOWNLOAD等待下载完成 点击ideaIU-2019.2.exe一路next      可以在这一步选一下 继续next         ...

  3. ngxin安装之yum安装

    nginx部署至yum安装 1. 配置nginx所需的YUM源 [root@nginx]# cat /etc/yum.repos.d/yum.repo [nginx-stable] name=ngin ...

  4. Python之变量、常量以及注释

    Python之变量.常量以及注释 一.什么是变量 变量,是用于在内存中存放程序数据的容器,怎么理解呢? 计算机的最核心的功能j就是"计算",计算需要数据源,数据源存在在内存里,比如 ...

  5. SpringBoot读取配置文件源码探究

    1. SpringBoot读取配置文件源码探究 1.1. 概览 springboot的源码是再原来的Spring源码上又包了一层,看过spring源码都知道,当我们从入口debug进去的时候,原来的S ...

  6. HDU 6242

    题意略. 思路:这个题的思路非常诡异.由于题目保证存在这样一个圆,那么每个点在这个圆上的概率是1/2,我任选3个点,这3个点都在这个圆上的概率是1 / 8. 不都在这个圆上的概率是7 / 8,在这样选 ...

  7. Linux 防火墙开放、查询、关闭端口

    1. 开放指定端口 firewall-cmd --zone=public --add-port=5121/tcp --permanent # --permanent 永久生效,如果不加此条,重启后该命 ...

  8. The Best Path(HDU5883)[欧拉路]2016青岛online

    题库链接:http://acm.hdu.edu.cn/showproblem.php?pid=5883 欧拉回路裸题,第一次接触欧拉路的我是真的长见识了^-^ 懂了欧拉路这道题就是没什么问题了,欧拉路 ...

  9. vue.js如何根据后台返回来的图片url进行图片下载

    最近在做一个前端vue.js对接的功能模块时,需要实现一个下载图片的功能,后台返回来的是一串图片url,试了很多种方法,发现点击下载时出来的效果都是跳着到一个新的图片网页,后来经过一番琢磨,终于解决了 ...

  10. c#搭建jenkins自动构建环境

    这边我使用的是参数化构建过程,文笔比较差劲,就直接上干货了 1.定义构造参数 2.设置jenkins工作空间目录,在此定义了版本号和工作目录构建参数 3.配置svn 4.构建触发器,用于轮询查看svn ...