国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

c學習筆記——自定義qsort函數

yanest / 2739人閱讀

摘要:一前言我們學習過的冒泡排序,插入排序,選擇排序等經典排序方法,為我們數據排序提供了穩定思路,但局限在于排序數據類型的單一。

一、前言

? ?我們學習過的冒泡排序,插入排序,選擇排序等經典排序方法,為我們數據排序提供了穩定思路,但局限在于排序數據類型的單一。為了解決這一問題,c語言中提供了庫函數qsort解決。我們今天就通過自定義函數實現qsort的功能,排序方法采用基本的冒泡排序


?二、從MSDN認識qsort

1.分析:

我們需要傳入四個變量:base——待排序數組的首元素地址;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? num——數組內的元素個數;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? width——每個元素的大小(單位為字節);

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?函數指針——傳入兩個數的地址,比較二者大小(需自己設計)

2.void*的特殊性

1.可以傳入任何類型的指針而不會報警告,適合我們實現任何數據類型排序的目的;

2.不可以對其進行解引用操作,除非通過強制類型轉換()確定其具體類型;

3.不可以對其進行加減運算,原因是不知道類型所以不知道步長,因此還是需要強制類型轉換


三、cmp_函數的實現

注意:都需要先進行強制類型轉換才可以解引用

1.比較int類型數據

int cmp_int(const void* e1, const void* e2){	return *(int*)e1 - *(int*)e2;}

2.比較char類型數據

char類型數據不可以用<>=進行比較,所以要用函數strcmp庫函數,頭文件為#include

int cmp_char(const void*e1, const void*e2){	return strcmp((char*)e1, (char*)e2);}

3.比較float類型函數

因為返回的是int類型,所以我們加入了判斷語句。用數的正負表示數的大小情況

int cmp_float(const void*e1, const void*e2){	if ((float*)e1 > (float*)e2)		return 1;	else if ((float*)e1 ==(float*)e2)		return 0;	else		return -1;}

4.比較結構體類型函數

結構體數組元素不可以直接比較,必須先選出結構體某一內容進行比較

typedef struct book{ 	char name[20];	int prince;                   }b;//重命名struct book為bint cmp_stru_price(const void*e1, const void*e2){	return ((b*)e1)->prince - ((b*)e2)->prince;}

注意!!!(b*)e1外面的括號不可以省略,因為->的優先級比強制類型轉換高


四、bubble_sort函數的實現

首先思考一個問題:既然傳入的指針為void*類型,如何實現步長的確定?聰明的科學家想到利用width作為我們的標準

void bubble_sort(void*base,int sz,int width,int(*cmp)(void*,void*)){	int i; int j;	for (i = 0; i < sz - 1; i++)	{		for (j = 0; j < sz - 1-i; j++)		{			if (cmp((char*)base + width*j, (char*)base + width*(j + 1))>0)			{				swap((char*)base + width*j, (char*)base + width*(j + 1),width);			}		}	}}

分析:

1.int(*)(void*,void*)是一個函數指針,指向我們之前設計的大小比較函數

2.在使用base的時候要先強制類型轉換才可以作加減運算

3.漂亮的地方在于,不管實際傳入的base是什么類型,我們都將其轉化為char*類型的指針,因為char*的步長最小為1,加上width就可以準確指向下一個?

以int為例,width為4,所及就可以指向下一個元素

?

?


五、swap函數的實現

void swap(char*buff1,char*buff2,int width){	int i;	for (i = 0; i < width; i++)	{		int tmp = *buff1;		*buff1 = *buff2;		*buff2 = tmp;		buff1++;		buff2++;	}}

值得關注的是,交換不是一次就可以了,因為我們現在是char*類型的指針,如上圖所畫,一次只能交換一格,如交換int的,要交換4次


六、重難點總結

1.函數指針的使用,使我們每次只需導入大小比較函數的地址即可,而不必寫多個函數,分別含有不同的大小比較函數,減少了重復代碼的出現

?2.width的使用相當于告訴了我們進行比較的數組元素的類型,滿足我們實現各種數據類型排序的需求

3.void*函數海納百川,方便了我們的輸入,只是注意在使用時的強制類型轉化,否則無法使用


希望上述的總結對大家的理解有幫助,也更好的欣賞回調函數(這里為用函數指針調用函數)的魅力。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/118801.html

相關文章

  • C語言進階:指針進階續

    摘要:故使用無具體類型,又稱通用類型,即可以接收任意類型的指針,但是無法進行指針運算解引用,整數等。求指針所占字節而不是解引用訪問權限大小。數組就是整個數組的大小,數組元素則是數組元素的大小,指針大小都為。 ...

    ingood 評論0 收藏0
  • C語言qsort()函數的使用(詳解)

    摘要:參數含義上圖是函數各個參數的含義,讓我們一個個來看。使用方式頭文件要使用函數我們首先需要引用一個頭文件的實現函數給函數規定了特定的參數。因此我們設計函數時要嚴格遵守其參數設定。 目錄 1.參數含義 1.首元素地址base 2.元素個數num 3.元素大小size 4.自定義比較函數compa...

    wangym 評論0 收藏0
  • C | 指針的相關知識(二)

    摘要:回調函數不是由該函數的實現方直接調用,而是在特定的事件或條件發生時由另外的一方調用的,用于對該事件或條件進行響應。 目錄 前言無類型指針結構體指針枚舉變量指針函數...

    alin 評論0 收藏0
  • 使用回調函數通過冒泡排序模擬實現qsort函數

    摘要:如果你把函數的指針地址作為參數傳遞給另一個函數,當這個指針被用來調用其所指向的函數時,我們就說這是回調函數。回調函數不是由該函數的實現方直接調用,而是在特定的事件或條件發生時由另外的一方調用的,用于對該事件或條件進行響應。 ...

    MasonEast 評論0 收藏0

發表評論

0條評論

yanest

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<