【C/C++】qsort函數的使用方法和細節

来源:https://www.cnblogs.com/z-y-k/archive/2019/09/22/11569933.html
-Advertisement-
Play Games

函數概述 qsort 為quick sort的簡寫,意為快速排序,主要用於對各種數組的排序,在頭文件stdlib.h中。 因為數組的元素可能是任何類型的,甚至是結構或者聯合,所以必須高數函數qsort如何確定兩個數組元素哪一個“更小”,這就需要我們給出比較的規則,即什麼算大,什麼算小。 通過編寫比較 ...


函數概述

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);  
    }

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一 web框架的本質及自定義web框架 我們可以這樣理解:所有的Web應用本質上就是一個socket服務端,而用戶的瀏覽器就是一個socket客戶端,基於請求做出響應,客戶都先請求,服務端做出對應的響應,按照http協議的請求協議發送請求,服務端按照http協議的響應協議來響應請求,這樣的網路通信, ...
  • 一、創建一個學生類 每個學生都有學號信息,但是每一個學生的學號都是不同的,所以要訪問這個學號必須先創建對象,通過對象去訪問學號信息,學號信息不能直接通過“類”去訪問,所以這種成員變數又被稱為“實例變數” 註意: (1)對象又被稱為實例,實例變數又被稱為對象變數(對象級別的變數) (2)不創建對象,這 ...
  • 除了基本的docker pull、docker image、docker ps,還有一些命令及參數也很重要,在此記錄下來避免遺忘。 環境信息 以下是本次操作的環境: 1. 操作系統:CentOS Linux release 7.7.1908 2. Docker:19.03.2 假設當前環境正運行著兩 ...
  • PHP開啟目錄引索 一. 前言 不知為何對nginx情有獨鍾, 最近練習php, 為了方便寫代碼, 便想要開啟nginx的目錄索引功能, 顯然不如Apache開啟的方便, 幾次嘗試都崩了... 我這個小白確實有點看不懂nginx的配置文件. 不過最後還是成功了, 記錄一下, 萬一哪天忘了, 回來看看 ...
  • 今天開始改變寫博客風格,其他不多說. 今天題目如下: 我先寫自己的寫程式的方法,先直接看正確完整的代碼直接往下看 一開始看了題目,我發現的規律是"alex"、"name"、"hobby"由多個變成一個 因此我想到了用set集合去重 我是想要把user_list列表的鍵收集起來變成列表,然後通過set ...
  • Spring Boot 項目中使用 JSP: 項目結構:需要添加webapp文件夾用來存放目錄 jsp 文件 在配置文件application.properties中指定 jsp 的位置和尾碼。spring.mvc.view.prefix=/WEB-INF/jsp/spring.mvc.view.s ...
  • 上篇文章 "SpringBoot自動裝配原理解析" 中,我們分析了SpringBoot的自動裝配原理以及 註解的原理,本篇文章則繼續基於上篇文章中的main方法來分析 這個類 點擊 方法一路跟蹤下來,發現首先做的是實例化 對象實例 1. 首先看一下 方法 大抵意思就是根據當前項目中是否存在上方的幾個 ...
  • 最近將萬方數據的爬取代碼進行了重構,速度大概有10w每小時吧,因為屬於公司項目,代碼暫時就不開源了,所以在這裡先說說思路和一些註意事項吧,順帶吐槽一下萬方。 先上圖: 其實邏輯也蠻簡單的,醫學類的期刊分了16個大類,那麼首先手動將這16大類所對應的唯一id拿下來拼接出該類型的url,然後翻頁請求它就 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...