“海压竹枝低复举,风吹山角晦还明” ——宋·陈与义《观雨》
目录
1.模拟实现qsort函数进行整型排序(升序版---可进行更改)
后记:●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教! ——By 作者:新晓·故知
7. 指向函数指针数组的指针
前章回顾:编辑
编辑
编辑
编辑
编辑
编辑
编辑编辑
编辑编辑
编辑
编辑
指向函数指针数组的指针是一个 指针
指针指向一个 数组 ,数组的元素都是 函数指针 ;
如何定义?编辑
8. 回调函数
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
首先演示一下qsort函数的使用:
编辑
#include <stdio.h> //qosrt函数的使用者得实现一个比较函数 int int_cmp(const void* p1, const void* p2) { return (*(int*)p1 - *(int*)p2); } int main() { int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 }; int i = 0; qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp); for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) { printf("%d ", arr[i]); } printf("\n"); return 0; }
使用回调函数,模拟实现qsort(采用冒泡的方式)。
注意:这里第一次使用 void* 的指针,讲解 void* 的作用。
#include <stdio.h> int int_cmp(const void* p1, const void* p2) { return (*(int*)p1 - *(int*)p2); } void _swap(void* p1, void* p2, int size) { int i = 0; for (i = 0; i < size; i++) { char tmp = *((char*)p1 + i); *((char*)p1 + i) = *((char*)p2 + i); *((char*)p2 + i) = tmp; } } void bubble(void* base, int count, int size, int(*cmp)(void*, void*)) { int i = 0; int j = 0; for (i = 0; i < count - 1; i++) { for (j = 0; j < count - i - 1; j++) { if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0) { _swap((char*)base + j * size, (char*)base + (j + 1) * size, size); } } } } int main() { int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 }; //char *arr[] = {"aaaa","dddd","cccc","bbbb"}; int i = 0; bubble(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int), int_cmp); for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) { printf("%d ", arr[i]); } printf("\n"); return 0; }
编辑
冒泡排序:(操作对象---整型元素int型)
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 print_arr(int arr[], int sz) { int i = 0; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } printf("\n"); } int main() { int arr[] = { 1,4,2,6,5,3,7,9,0,8 }; int sz = sizeof(arr) / sizeof(arr[0]); bubble_sort(arr, sz); print_arr(arr, sz); return 0; }
编辑
编辑
编辑
编辑编辑
编辑
编辑
编辑
编辑
#include<stdio.h> #include<stdlib.h> 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 print_arr(int arr[], int sz) { int i = 0; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } printf("\n"); } //qsort - 库函数 - 快速排序的方法实现的 //比较e1和e2指向的元素 int cmp_int(const void* e1, const void* e2) { if (*(int*)e1 > *(int*)e2) return 1; else if(*(int*)e1 < *(int*)e2) return -1; else return 0; } //测试qsort排序整型数组 int main() { int arr[] = { 1,4,2,6,5,3,7,9,0,8 }; int sz = sizeof(arr) / sizeof(arr[0]); qsort(arr, sz, sizeof(arr[0]), cmp_int); print_arr(arr, sz); return 0; }
代码优化:
#include<stdio.h> #include<stdlib.h> 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 print_arr(int arr[], int sz) { int i = 0; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } printf("\n"); } //qsort - 库函数 - 快速排序的方法实现的 //比较e1和e2指向的元素 int cmp_int(const void* e1, const void* e2) { return *(int*)e1 - *(int*)e2; //此语句默认排序方式为升序 //return *(int*)e2 - *(int*)e1; //此语句默认排序方式为降序 //if (*(int*)e1 > *(int*)e2) // return 1; //else if(*(int*)e1 < *(int*)e2) // return -1; //else // return 0; } //测试qsort排序整型数组 int main() { int arr[] = { 1,4,2,6,5,3,7,9,0,8 }; int sz = sizeof(arr) / sizeof(arr[0]); qsort(arr, sz, sizeof(arr[0]), cmp_int); print_arr(arr, sz); return 0; }
任意类型排序函数:
编辑
1.测试qsort排序结构体数据
(1)按照成绩进行排序(升序版---可进行更改)
#include<stdio.h> #include<stdlib.h> //qsort - 库函数 - 快速排序的方法实现的 //测试qsort排序结构体数据 struct Stu { char name[20]; int age; float score; }; //按照成绩进行排序(升序版) int cmp_stu_by_socre(const void* e1, const void* e2) { if (((struct Stu*)e1)->score > ((struct Stu*)e2)->score) { return 1; } else if (((struct Stu*)e1)->score < ((struct Stu*)e2)->score) { return -1; } else { return 0; } } void print_stu(struct Stu arr[], int sz) { int i = 0; for (i = 0; i < sz; i++) { printf("%s %d %f\n", arr[i].name, arr[i].age, arr[i].score); } printf("\n"); } void test2() { struct Stu arr[] = { {"zhangsan",20,87.5f},{"lisi",22,99.0f},{"wangwu", 19, 90.8f} }; int sz = sizeof(arr) / sizeof(arr[0]); qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_socre); print_stu(arr, sz); } int main() { test2(); return 0; }
(2)按照年龄进行排序(升序版---可进行更改)
#include<stdio.h> #include<stdlib.h> //qsort - 库函数 - 快速排序的方法实现的 //测试qsort排序结构体数据 struct Stu { char name[20]; int age; float score; }; //按照年龄进行排序(升序版) int cmp_stu_by_age(const void* e1, const void* e2) { return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age; } void print_stu(struct Stu arr[], int sz) { int i = 0; for (i = 0; i < sz; i++) { printf("%s %d %f\n", arr[i].name, arr[i].age, arr[i].score); } printf("\n"); } void test2() { struct Stu arr[] = { {"zhangsan",20,87.5f},{"lisi",22,99.0f},{"wangwu", 19, 90.8f} }; int sz = sizeof(arr) / sizeof(arr[0]); qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_age); print_stu(arr, sz); } int main() { test2(); return 0; }
(3)按照姓名进行排序(升序版---可进行更改)
此处注意函数strcmp的返回值(>0、=0、<0)功能及含义!
#include<stdio.h> #include<stdlib.h> #include<string.h> //qsort - 库函数 - 快速排序的方法实现的 //测试qsort排序结构体数据 struct Stu { char name[20]; int age; float score; }; //按照姓名进行排序(升序版) int cmp_stu_by_name(const void* e1, const void* e2) { return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name); } void print_stu(struct Stu arr[], int sz) { int i = 0; for (i = 0; i < sz; i++) { printf("%s %d %f\n", arr[i].name, arr[i].age, arr[i].score); } printf("\n"); } void test2() { struct Stu arr[] = { {"zhangsan",20,87.5f},{"lisi",22,99.0f},{"wangwu", 19, 90.8f} }; int sz = sizeof(arr) / sizeof(arr[0]); qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_name); print_stu(arr, sz); } int main() { test2(); return 0; }
注:
若进行排序的是汉字,因为汉字也是存储在字符串中,且一个汉字占据两个字符,而对于strcmp函数,将存放在内存中的数据一对字节、一对字节的进行比较,(无论其存储的是汉字还是阿拉伯数字等),每对字节进行比较直至结束。 (比较的是字母对应的ASCII码值!)
编辑
模拟qsort函数:
1.模拟实现qsort函数进行整型排序(升序版---可进行更改)
模拟实现qsort函数进行整型排序 #include<stdio.h> //qsort - 库函数 - 快速排序的方法实现的 void print_arr(int arr[], int sz) { int i = 0; for (i = 0; i < sz; i++) { printf("%d ", arr[i]); } printf("\n"); } //比较e1和e2指向的元素 int cmp_int(const void* e1, const void* e2) { return *(int*)e1 - *(int*)e2; } 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++; } } void bubble_sort(void* base, int sz, int width, int(*cmp)(const void* e1, const void* e2)) { 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]) if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0) { //两个元素的交换 Swap((char*)base + j * width, (char*)base + (j + 1) * width, width); } } } } void test3() { 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(arr, sz); } int main() { test3(); return 0; }
2.模拟实现qsort函数进行结构体数据排序
(1)按照成绩进行排序(升序版---可进行更改)
#include<stdio.h> #include<stdlib.h> #include<string.h> //模拟实现qsort函数进行结构体数据排序 struct Stu { char name[20]; int age; float score; }; //按照成绩进行排序(升序版) int cmp_stu_by_socre(const void* e1, const void* e2) { if (((struct Stu*)e1)->score > ((struct Stu*)e2)->score) { return 1; } else if (((struct Stu*)e1)->score < ((struct Stu*)e2)->score) { return -1; } else { return 0; } } 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++; } } void bubble_sort(void* base, int sz, int width, int(*cmp)(const void* e1, const void* e2)) { 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]) 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_stu(struct Stu arr[], int sz) { int i = 0; for (i = 0; i < sz; i++) { printf("%s %d %f\n", arr[i].name, arr[i].age, arr[i].score); } printf("\n"); } void test4() { struct Stu arr[] = { {"zhangsan",20,87.5f},{"lisi",22,99.0f},{"wangwu", 19,90.8f} }; int sz = sizeof(arr) / sizeof(arr[0]); bubble_sort(arr, sz, sizeof(arr[0]), cmp_stu_by_socre); print_stu(arr, sz); } int main() { test4(); return 0; }
(2)按照年龄进行排序(升序版---可进行更改)
#include<stdio.h> #include<stdlib.h> #include<string.h> //模拟实现qsort函数进行结构体数据排序 struct Stu { char name[20]; int age; float score; }; //按照年龄进行排序(升序版) int cmp_stu_by_age(const void* e1, const void* e2) { return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age; } 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++; } } void bubble_sort(void* base, int sz, int width, int(*cmp)(const void* e1, const void* e2)) { 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]) 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_stu(struct Stu arr[], int sz) { int i = 0; for (i = 0; i < sz; i++) { printf("%s %d %f\n", arr[i].name, arr[i].age, arr[i].score); } printf("\n"); } void test4() { struct Stu arr[] = { {"zhangsan",20,87.5f},{"lisi",22,99.0f},{"wangwu", 19, 90.8f} }; int sz = sizeof(arr) / sizeof(arr[0]); bubble_sort(arr, sz, sizeof(arr[0]), cmp_stu_by_age); print_stu(arr, sz); } int main() { test4(); return 0; }
(3)按照姓名进行排序(升序版---可进行更改)
此处注意函数strcmp的返回值(>0、=0、<0)功能及含义!
#include<stdio.h> #include<stdlib.h> #include<string.h> //模拟实现qsort函数进行结构体数据排序 struct Stu { char name[20]; int age; float score; }; //按照姓名进行排序(升序版) int cmp_stu_by_name(const void* e1, const void* e2) { return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name); } 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++; } } void bubble_sort(void* base, int sz, int width, int(*cmp)(const void* e1, const void* e2)) { 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]) 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_stu(struct Stu arr[], int sz) { int i = 0; for (i = 0; i < sz; i++) { printf("%s %d %f\n", arr[i].name, arr[i].age, arr[i].score); } printf("\n"); } void test4() { struct Stu arr[] = { {"zhangsan",20,87.5f},{"lisi",22,99.0f},{"wangwu", 19, 90.8f} }; int sz = sizeof(arr) / sizeof(arr[0]); bubble_sort(arr, sz, sizeof(arr[0]), cmp_stu_by_name); print_stu(arr, sz); } int main() { test4(); return 0; }
编辑
编辑
编辑
编辑