最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語言庫函數(shù)qsort的使用詳解

 更新時間:2022年06月14日 08:16:37   作者:蔣靈瑜的流水賬  
C語言庫函數(shù)中的qsort的是一個回調(diào)函數(shù),回調(diào)函數(shù)就是一個通過函數(shù)指針調(diào)用的函數(shù),這篇文章主要介紹了C語言庫函數(shù)qsort的使用,需要的朋友可以參考下

一、回調(diào)函數(shù)

C語言庫函數(shù)中的qsort的是一個回調(diào)函數(shù),回調(diào)函數(shù)就是一個通過函數(shù)指針調(diào)用的函數(shù)。如果把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個 函數(shù),當這個指針被用來調(diào)用其所指向的函數(shù)時,我們就說這是回調(diào)函數(shù)?;卣{(diào)函數(shù)不是由該函數(shù)的實現(xiàn)方直接調(diào)用,而是在特定的事件或條件發(fā)生時由另外的一方調(diào)用的,用于對該事件或條件進行響應(yīng)。

二、庫函數(shù)qsort

void* base:要排序的數(shù)據(jù)的起始位置

size_t num:待排序數(shù)據(jù)的元素個數(shù)

size_t width:待排序的數(shù)據(jù)元素的大小,單位是字節(jié)

int(__cdecl*compare)(constvoid*elem1,constvoid*elem2):把比較函數(shù)的地址傳給cmp,e1和e2是要比較的兩個元素的地址。(__cdecl是函數(shù)調(diào)用約定)

注意:最后一個函數(shù)參數(shù)是一個函數(shù)指針,所以在調(diào)用庫函數(shù)qsort()的時候,傳的參數(shù)是比較函數(shù)的地址。

1、e1小于e2,返回值小于0;

2、e1等于e2,返回0;

3、e1大于e2,返回值大于0。

三、使用qsort排序整型數(shù)組

#include <stdlib.h>
#include <stdio.h>
int int_cmp(const void* e1, const void* e2)
{
	return *(int*)e1 - *(int*)e2;//升序排序
}
int main()
{
	int arr[10] = { 9,8,7,6,5,2,4,3,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, sz, sizeof(arr[0]), int_cmp);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);//打印0 1 2 3 4 5 6 7 8 9
	}
	return 0;
}

庫函數(shù)qsort的比較函數(shù)是需要自己實現(xiàn)的,并且已經(jīng)給定了比較函數(shù)的兩個形參。因為e1和e2是無類型指針,不能解引用和加減。所以此處使用時需要先將指針類型前置類型轉(zhuǎn)換為int*,再進行解引用操作。

此處可以加深回調(diào)函數(shù)的理解:int_cmp是本人來實現(xiàn)的,當程序運行到qsort函數(shù)時,由庫函數(shù)qsort對int_cmp進行調(diào)用。這就是回調(diào)函數(shù)。

四、使用qsort排序結(jié)構(gòu)體

1、使用qsort排序結(jié)構(gòu)體中的字符成員

先創(chuàng)建一個學生的結(jié)構(gòu)體類型,定義一個結(jié)構(gòu)體類型的學生數(shù)組,數(shù)組內(nèi)包含3名學生的信息。通過qsort函數(shù)進行排序。在實現(xiàn)str_name_cmp函數(shù)時,需要先將e1和e2先強制類型轉(zhuǎn)換為struct Stu*類型,由于strcmp函數(shù)的返回值剛好契合str_name_cmp函數(shù),可以直接使用return將返回值帶回。通過打印可以發(fā)現(xiàn)三名同學已經(jīng)按ASCII碼完成排序。

2、使用qsort排序結(jié)構(gòu)體中的整型成員

#include <stdlib.h>
#include <stdio.h>
struct Stu
{
	char name[20];
	int age;
};
int str_age_cmp(const void* e1, const void* e2)
{
	return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
int main()
{
	struct Stu s[] = { {"zhangsan",18},{"lisi",17},{"wangwu",22} };
	int sz = sizeof(s) / sizeof(s[0]);
	qsort(s, sz, sizeof(s[0]), str_age_cmp);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", s[i].age);//輸出17 18 22
	}
	return 0;
}

排序結(jié)構(gòu)體整型成員和排序整型數(shù)組、結(jié)構(gòu)體字符成員方式相似。

五、基于冒泡排序的庫函數(shù)qsort的模擬實現(xiàn)

1、使用改寫函數(shù)排序整型數(shù)組

#include <stdlib.h>
#include <stdio.h>
int int_cmp(const void* e1, const void* e2)//比較函數(shù)
{
	return *(int*)e1 - *(int*)e2;//升序排序
}
Swap(char* p1, char* p2, size_t width)
{
	for (int i = 0; i < width; i++)//每個字節(jié)交換
	{
		int tmp = *p1;
		*p1 = *p2;
		*p2 = tmp;
		p1++;
		p2++;
	}
}
void qsort_bubble(void* base, size_t sz, size_t width, int(* compare)(const void* e1, const void* e2))
{//基于庫函數(shù)qsort進行改寫的冒泡排序
	for (int i = 0; i < sz-1; i++)
	{
		int change = 0;
		for (int j = 1; j < sz - i; j++)
		{
            //交換
			if (compare((char*)base+(j-1)*width , (char*)base+j*width)>0)
			{
				Swap((char*)base + (j - 1) * width, (char*)base + j * width,width);
				change = 1;
			}
		}
		if (change == 0)
			break;
	}
}
int main()
{
	int arr[10] = { 9,8,7,6,5,2,4,3,1,0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	qsort_bubble(arr, sz,sizeof(arr[0]),int_cmp);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

qsort_bubble函數(shù)中,采用冒泡排序的比較方式,形參模仿庫函數(shù)qsort中的形參。

在函數(shù)內(nèi)部調(diào)用compare時(compare是比較函數(shù)的地址),由于外部比較的數(shù)據(jù)類型不可知,故使用最小內(nèi)置類型char和數(shù)據(jù)類型的長度width來表示外部類型所占字節(jié)。

2、使用改寫函數(shù)排序結(jié)構(gòu)體中的字符成員

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct Stu//定義結(jié)構(gòu)體
{
	char name[20];
	int age;
};
int str_name_cmp(const void* e1, const void* e2)//字符的比較函數(shù)
{
	return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
Swap(char* p1, char* p2, size_t width)//交換函數(shù)
{
	for (int i = 0; i < width; i++)
	{
		int tmp = *p1;
		*p1 = *p2;
		*p2 = tmp;
		p1++;
		p2++;
	}
}
void qsort_bubble(void* base, size_t sz, size_t width, int(*compare)(const void* e1, const void* e2))
{基于庫函數(shù)qsort進行改寫的冒泡排序
	for (int i = 0; i < sz - 1; i++)
	{
		int change = 0;
		for (int j = 1; j < sz - i; j++)
		{
			if (compare((char*)base + (j - 1) * width, (char*)base + j * width)>0)
			{
				Swap((char*)base + (j - 1) * width, (char*)base + j * width, width);
				change = 1;
			}
		}
		if (change == 0)
			break;
	}
}
int main()
{
	struct Stu s[] = {{"zhangsan",18},{"lisi",17},{"wangwu",22}};
	int sz = sizeof(s) / sizeof(s[0]);
	qsort(s, sz, sizeof(s[0]), str_name_cmp);
	for (int i = 0; i < sz; i++)
	{
		printf("%s ", s[i].name);
	}
	return 0;
}

輸出結(jié)果lisi wangwu zhangsan,理解方式和上方例子一樣。

3、對庫函數(shù)qsort的總結(jié)

第一次使用庫函數(shù)qsort的時候,肯定會疑惑,為什么e1-e2的返回值大于0時,升序排序;反之降序?

我們在模擬實現(xiàn)的時候,在冒泡排序內(nèi)部調(diào)用compare這個函數(shù)地址,傳參時,如果前一個元素的值大于后一個元素,那么傳入比較函數(shù),e1-e2>0,進行交換,交換完畢后e1<e2,實現(xiàn)了升序排序!

如果要實現(xiàn)降序排序,在比較函數(shù)內(nèi)使用e2-e1即可,意思是后一個元素大于前一個元素,進行交換,交換完畢后e1>e2,實現(xiàn)了降序排序!

六、力扣977#中庫函數(shù)qsort的使用

使用pow函數(shù)對數(shù)組元素逐個平方。由于素組內(nèi)存在負數(shù),所以平方后數(shù)組可能亂序,需要重新排序,這里可以使用庫函數(shù)qsort進行排序。

 int compare(const void* elem1,const void* elem2)//比較函數(shù)
 {
     return *(int*)elem1-*(int*)elem2;
 }
int* sortedSquares(int* nums, int numsSize, int* returnSize){
    *returnSize=numsSize;
    for(int i=0;i<numsSize;i++)
    {
        nums[i]=pow(nums[i],2);
    }
    qsort(nums,numsSize,sizeof(nums[0]),compare);//庫函數(shù)qsort的使用
    return nums;
}

但是平常刷題是還是不建議無腦上qsort,需要根據(jù)題目要求合理的選擇排序算法。

到此這篇關(guān)于C語言庫函數(shù)qsort的使用的文章就介紹到這了,更多相關(guān)C語言庫函數(shù)qsort內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 嵌入式項目使用C語言結(jié)構(gòu)體位段特性實現(xiàn)斷言宏校驗數(shù)據(jù)范圍有效性的方法

    嵌入式項目使用C語言結(jié)構(gòu)體位段特性實現(xiàn)斷言宏校驗數(shù)據(jù)范圍有效性的方法

    今天小編就為大家分享一篇關(guān)于嵌入式項目使用C語言結(jié)構(gòu)體位段特性實現(xiàn)斷言宏校驗數(shù)據(jù)范圍有效性的方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • C語言常見的指針筆試題解析

    C語言常見的指針筆試題解析

    在我們學習指針之后,應(yīng)該在實際應(yīng)用中去理解和掌握它,畢竟實踐才是檢驗真理的唯一標準,我們以后在找工作的過程中免不了會遇到與指針相關(guān)的試題,本篇文章可以幫助我們提前了解一些常見的指針考點,需要的可以了解一下
    2022-10-10
  • 在vs2010中,輸出當前文件路徑與源文件當前行號的解決方法

    在vs2010中,輸出當前文件路徑與源文件當前行號的解決方法

    本篇文章是對在vs2010中,輸出當前文件路徑與源文件當前行號的解決方法進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C/C++ Qt 數(shù)據(jù)庫與Chart歷史數(shù)據(jù)展示

    C/C++ Qt 數(shù)據(jù)庫與Chart歷史數(shù)據(jù)展示

    這篇文章主要介紹了Qt利用Qchart組件展示數(shù)據(jù)庫中的歷史數(shù)據(jù)。文中的示例代碼講解清晰,具有一定的學習和工作價值,感興趣的小伙伴可以學習一下
    2021-12-12
  • ffmpeg?在?win平臺下的編譯以及集成

    ffmpeg?在?win平臺下的編譯以及集成

    這篇文章主要為大家介紹了ffmpeg?在?win平臺下的編譯以及集成詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2023-05-05
  • C語言基礎(chǔ) strlen 函數(shù)

    C語言基礎(chǔ) strlen 函數(shù)

    這篇文章主要介紹了C語言基礎(chǔ) strlen 函數(shù),在C 語言中,char 字符串也是一種非常重要的數(shù)據(jù)類型,我們可以使用 strlen 函數(shù)獲取字符串長度,這就是C語言strlen 函數(shù)的作用,下面我們來簡單介紹該內(nèi)容,需要的朋友可以參考以下
    2021-10-10
  • C++線程池實現(xiàn)代碼

    C++線程池實現(xiàn)代碼

    C++11中,線程我們可以理解為對應(yīng)一個thread對象,任務(wù)可以理解為要執(zhí)行的函數(shù),通常是耗時的函數(shù)。線程過多或者頻繁創(chuàng)建和銷毀線程會帶來調(diào)度開銷,進而影響緩存局部性和整體性能
    2021-12-12
  • C++實現(xiàn)LeetCode(37.求解數(shù)獨)

    C++實現(xiàn)LeetCode(37.求解數(shù)獨)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(37.求解數(shù)獨),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • c++ 內(nèi)聯(lián)函數(shù)和普通函數(shù)的區(qū)別

    c++ 內(nèi)聯(lián)函數(shù)和普通函數(shù)的區(qū)別

    內(nèi)聯(lián)函數(shù)是c++為了提高程序的運行速度做的改進,那么內(nèi)聯(lián)函數(shù)和普通函數(shù)的區(qū)別是什么,本文就來詳細的介紹一下,感興趣的朋友可以了解一下
    2021-05-05
  • C語言實現(xiàn)繪制貝塞爾曲線的函數(shù)

    C語言實現(xiàn)繪制貝塞爾曲線的函數(shù)

    貝塞爾曲線,又稱貝茲曲線或貝濟埃曲線,是應(yīng)用于二維圖形應(yīng)用程序的數(shù)學曲線。本文將利用C語言實現(xiàn)繪制貝塞爾曲線的函數(shù),需要的可以參考一下
    2022-12-12

最新評論

柳州市| 松江区| 新兴县| 迭部县| 南郑县| 陆丰市| 准格尔旗| 秦安县| 灌南县| 贡觉县| 疏勒县| 延津县| 吴江市| 正定县| 军事| 霍州市| 汽车| 肇东市| 拉孜县| 商河县| 南木林县| 偃师市| 宿松县| 定西市| 黄骅市| 分宜县| 寿光市| 凤凰县| 英吉沙县| 包头市| 马鞍山市| 个旧市| 平乡县| 清徐县| 松溪县| 邵武市| 如东县| 正镶白旗| 乡城县| 南漳县| 武平县|