目錄
思維導(dǎo)圖:
回調(diào)函數(shù)
qsort函數(shù)介紹
模擬實(shí)現(xiàn)qsort
寫(xiě)在最后:
思維導(dǎo)圖:
回調(diào)函數(shù)
什么是回調(diào)函數(shù)?
回調(diào)函數(shù)是一個(gè)通過(guò)函數(shù)指針調(diào)用的函數(shù)。
將一個(gè)函數(shù)指針作為參數(shù)傳遞給一個(gè)函數(shù),當(dāng)這個(gè)指針被用來(lái)調(diào)用所指向函數(shù)時(shí),
我們就將此稱為回調(diào)函數(shù)。
在舉例之前,我們先學(xué)習(xí)一個(gè)C語(yǔ)言的庫(kù)函數(shù)qsort。? ? ? ??
qsort函數(shù)介紹
qsort函數(shù)是一個(gè)排序函數(shù),可以幫助我們排序。
我們?yōu)槭裁匆獙W(xué)習(xí)這樣一個(gè)函數(shù)呢?
我們對(duì)一個(gè)整形數(shù)組進(jìn)行排序:
例:
#include <stdio.h>
void print(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
void bubble_sort(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz - 1; i++)
{
int j = 0;
for (j = 0; j < sz - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
void test()
{
int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz);//冒泡排序
print(arr, sz);//打印
}
int main()
{
test();//分裝函數(shù)
return 0;
}
輸出:
輸出:0 1 2 3 4 5 6 7 8 9
但是如果我們想對(duì)一個(gè)結(jié)構(gòu)體進(jìn)行排序,冒泡排序就承擔(dān)不了這個(gè)任務(wù)了,
(不止結(jié)構(gòu)體,像浮點(diǎn)數(shù)啊,字符數(shù)組啊,冒泡排序都無(wú)法工作)
這個(gè)時(shí)候,我們就能使用qsort函數(shù)幫我們排序。
我們可以通過(guò)cplusplus學(xué)習(xí)一下這個(gè)函數(shù):
通過(guò)閱讀介紹,我們得知qsort的功能:
對(duì)數(shù)組中由指針指向的元素進(jìn)行排序,根據(jù)每個(gè)元素字節(jié)長(zhǎng)度,使用函數(shù)確定順序。
此函數(shù)使用的快速排序算法通過(guò)調(diào)用指定的函數(shù)來(lái)比較元素,并將指向它們的指針作為參數(shù)。
該函數(shù)不返回任何值,但通過(guò)重新排序數(shù)組的元素來(lái)修改指向的數(shù)組的內(nèi)容。
以及使用該函數(shù)需要傳遞的參數(shù):
int main()
{
void qsort(void* base, size_t num, size_t size,
int (*compar)(const void*, const void*));
//一個(gè)指針,兩個(gè)無(wú)符號(hào)整數(shù),一個(gè)函數(shù)指針
return 0;
}
?這個(gè)庫(kù)函數(shù)需要調(diào)用的頭文件是:<stdlib.h>
以及各個(gè)參數(shù)的不同意思:
#include <stdio.h>
int main()
{
void qsort(void* base,
size_t num,
size_t size,
int (*compar)(const void*, const void*));
//void*base是指向要排序的數(shù)組的第一個(gè)對(duì)象的指針,轉(zhuǎn)換為void*類型
//size_t num是數(shù)組中的元素?cái)?shù)
//size_t size是數(shù)組中每個(gè)元素的大?。ㄒ宰止?jié)為單位)
//int (*compar)(const void*, const void*))是指向比較兩個(gè)元素的函數(shù)的指針
return 0;
}
?這樣,我們就能使用qsort函數(shù)幫助我們排序了:
例:
#include <stdio.h>
#include <stdlib.h>
struct Stu
{
char name[20];
int age;
};
int cmp_stu_by_age(const void* e1, const void* e2)
{
return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
//如果e1 > e2則返回>O的數(shù)
//如果e1 = e2則返回0
//如果e1 < e2則返回<0的數(shù)
}
void print(struct Stu* s, int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%s %d歲\n", (&s[i])->name,(&s[i])->age);
}
}
void test()
{
struct Stu s[3] = { {"張三",20}, {"李四", 50}, {"王五", 33} };
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);//排序
print(s, sz);//打印函數(shù)
}
int main()
{
test();//分裝函數(shù)
return 0;
}
輸出:
輸出:
張三 20歲
王五 33歲
李四 50歲
利用qsort函數(shù),我們成功給結(jié)構(gòu)體排序了。
模擬實(shí)現(xiàn)qsort
在模擬實(shí)現(xiàn)qsort時(shí),我們就要用到回調(diào)函數(shù)的思想:
例:
#include <stdio.h>
#include <stdlib.h>
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
//如果e1 > e2則返回>O的數(shù)
//如果e1 = e2則返回0
//如果e1 < e2則返回<0的數(shù)
}
//通過(guò)交換每個(gè)字節(jié)的形式,以達(dá)成交換兩個(gè)數(shù)的值的目的
void Swap(char* buf1, char* buf2, int width)
{
int i = 0;
for (i = 0; i < width; i++)
{
char tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
//這里將cmp_int函數(shù)的指針傳參
void bubble_sort(void* base, size_t sz, size_t width, int (*cmp)(const void* e1, const void* e2))
{
//趟數(shù)
size_t i = 0;
for (i = 0; i < sz - 1; i++)
{
//一趟冒泡排序的過(guò)程
size_t j = 0;
for (j = 0; j < sz - 1 - i; j++)
{ //這里運(yùn)用了回調(diào)函數(shù),在冒泡排序函數(shù)里調(diào)用cmp_int函數(shù),并判斷
//這里判斷函數(shù)返回的值大于零就進(jìn)入語(yǔ)句,排序后是升序數(shù)組
if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
{
//交換
Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
}
}
}
}
void print(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
void test()
{
int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);
print(arr, sz);//打印函數(shù)
}
int main()
{
test();//分裝函數(shù)
return 0;
}
輸出:
輸出:0 1 2 3 4 5 6 7 8 9
再用它來(lái)排序一下結(jié)構(gòu)體數(shù)組也是可以的:
例:
#include <stdio.h>
#include <stdlib.h>
struct Stu
{
char name[20];
int age;
};
int cmp_stu_by_age(const void* e1, const void* e2)
{
return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
//如果e1 > e2則返回>O的數(shù)
//如果e1 = e2則返回0
//如果e1 < e2則返回<0的數(shù)
}
//通過(guò)交換每個(gè)字節(jié)的形式,以達(dá)成交換兩個(gè)數(shù)的值的目的
void Swap(char* buf1, char* buf2, int width)
{
int i = 0;
for (i = 0; i < width; i++)
{
char tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
//這里將cmp_int函數(shù)的指針傳參
void bubble_sort(void* base, size_t sz, size_t width, int (*cmp)(const void* e1, const void* e2))
{
//趟數(shù)
size_t i = 0;
for (i = 0; i < sz - 1; i++)
{
//一趟冒泡排序的過(guò)程
size_t j = 0;
for (j = 0; j < sz - 1 - i; j++)
{ //這里運(yùn)用了回調(diào)函數(shù),在冒泡排序函數(shù)里調(diào)用cmp_int函數(shù),并判斷
//這里判斷函數(shù)返回的值大于零就進(jìn)入語(yǔ)句,排序后是升序數(shù)組
if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
{
//交換
Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
}
}
}
}
void print(struct Stu* s, int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%s %d歲\n", (&s[i])->name,(&s[i])->age);
}
}
void test()
{
struct Stu s[3] = { {"張三",20}, {"李四", 50}, {"王五", 33} };
int sz = sizeof(s) / sizeof(s[0]);
bubble_sort(s, sz, sizeof(s[0]), cmp_stu_by_age);
print(s, sz);//打印函數(shù)
}
int main()
{
test();//分裝函數(shù)
return 0;
}
輸出:
輸出:
張三 20歲
王五 33歲
李四 50歲
寫(xiě)在最后:
以上就是本篇文章的內(nèi)容了,感謝你的閱讀。
如果喜歡本文的話,歡迎點(diǎn)贊和評(píng)論,寫(xiě)下你的見(jiàn)解。
如果想和我一起學(xué)習(xí)編程,不妨點(diǎn)個(gè)關(guān)注,我們一起學(xué)習(xí),一同成長(zhǎng)。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-616051.html
之后我還會(huì)輸出更多高質(zhì)量?jī)?nèi)容,歡迎收看。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-616051.html
到了這里,關(guān)于C語(yǔ)言-指針進(jìn)階-qsort函數(shù)的學(xué)習(xí)與模擬實(shí)現(xiàn)(9.3)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!