1.回调函数是什么回调函数就是⼀个通过函数指针调⽤的函数。 如果你把函数的指针地址作为参数传递给另⼀个函数当这个指针被⽤来调⽤其所指向的函数 时被调⽤的函数就是回调函数。回调函数不是由该函数的实现⽅直接调⽤⽽是在特定的事件或条 件发⽣时由另外的⼀⽅调⽤的⽤于对该事件或条件进⾏响应。上一篇博客中写了一个简易的计算器int Add(int x, int y) { return x y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } void menu() { printf(-------------------------------\n); printf(----- 1. add 2. sub -----\n); printf(----- 3. mul 4. div -----\n); printf(----- 0. exit -----\n); printf(-------------------------------\n); } void calc(int (*pf)(int, int)) { int x 0; int y 0; int r 0; printf(请输入2个操作数:); scanf(%d%d, x, y); r pf(x, y); printf(结果是: %d\n, r); } int main() { int input 0; do { menu(); printf(请选择:); scanf(%d, input); switch (input) { case 1: calc(Add); break; case 2: calc(Sub); break; case 3: calc(Mul); break; case 4: calc(Div); break; case 0: printf(退出计算器\n); break; default: printf(输入错误请输入0~4的值\n); break; } } while (input); return 0; }这里int (*pf)(int, int)作为calc函数的参数说白了回调函数就是将函数的地址作为新函数的参数以达到进行调用的目的通常可起到简化代码量的作用。2. qsortqsort函数原型void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*))qsort是基于快速排序实现可排序任意类型的数据1.void*指向数组中第一个要排序的对象转换为void*。2.size_t num数组中按基数指向的元素数。3.size_t size数组中每个元素的字节大小。4.int (*compar)(const void*,const void*) 函数指针指向一个比较两个元素的函数。其中comp函数的规则如下返回值含义0p1指向的元素小于p2指向的元素0p1指向的元素大于p2指向的元素0p1指向的元素等于p2指向的元素由此我们可得到以下代码需包含stdlib.h int comp(const void* p1, const void* p2)//void*无法解引用需要强制转换为int*类型 { //if (*(int*)p1 *(int*)p2) // return -1; //else if (*(int*)p1 *(int*)p2) // return 1; //else // return 0; return(*(int*)p1 - *(int*)p2); } int main() { int arr[10] { 9,8,7,6,5,4,3,2,1,0 }; int len sizeof(arr) / sizeof(arr[0]); int size sizeof(int); qsort(arr,len,size,comp); for (int i 0; i 10; i) { printf(%d , *(arr i)); } return 0; }如果想要降序排列return(*(int*)p2 - *(int*)p1);也可对结构体排序struct Stu { char name[20]; int age; }; int cmp_age(const void* p1,const void* p2)//年龄升序 { return (*(struct Stu*)p1).age - (*(struct Stu*)p2).age; } int main() { struct Stu arr[] { {zhangsan,18},{lisi,25},{wangwu,15} }; int sz sizeof(arr) / sizeof(arr[0]); qsort(arr, sz, sizeof(arr[0]), cmp_age); for (int i 0; i sz; i) { printf(%d , arr[i].age); } return 0; }还可通过name进行排序等后面介绍strcmp函数后再实现。关于结构体其他的知识后面也会写博客介绍3. qsort函数的模拟实现使⽤回调函数模拟实现qsort采⽤冒泡的⽅式首先给出冒泡排序的基础代码void bubble_sort(int* arr, int sz) { int flag 1; for (int i 0; i sz - 1; i) { for (int j 0; j sz - i - 1; j) { if (arr[j] arr[j 1]) { int tmp arr[j]; arr[j] arr[j 1]; arr[j 1] tmp; flag 0; } } if (flag) return; } }仿造sqsort给出函数原型void my_qsort(void* base, size_t len, size_t size, int(*cmp)(const void* p1, const void* p2))主体还是两个for循环来控制排序的次数for (int i 0; i len - 1; i) { for (int j 0; j len - i - 1; j) { ....... } } }下面是否进行该次排序的条件可通过comp函数实现int comp(const void* p1, const void* p2) { return *(int*)p1 - *(int*)p2; }冒泡排序的交换可通过swap函数实现void swap(char* buf1, char* buf2, size_t size) { for (int i 0; i size; i) { char tmp *buf1; *buf1 *buf2; *buf2 tmp; buf1; buf2; } }注意由于这里是char* 类型的指针所以交换时只能一个字节一个字节的进行交换看图完整代码如下int comp(const void* p1, const void* p2) { return *(int*)p1 - *(int*)p2; } void swap(char* buf1, char* buf2, size_t size) { for (int i 0; i size; i) { char tmp *buf1; *buf1 *buf2; *buf2 tmp; buf1; buf2; } } void my_qsort(void* base, size_t len, size_t size, int(*cmp)(const void* p1, const void* p2)) { for (int i 0; i len - 1; i) { for (int j 0; j len - i - 1; j) { if (cmp((char*)base j * size, (char*)base j * size 1)) { swap((char*)base j * size, (char*)base (j 1) * size, size); } } } }这段代码只是为了帮我们理解qsort函数,实际操作直接使用qsort函数即可
深入理解指针5
发布时间:2026/5/25 9:01:30
1.回调函数是什么回调函数就是⼀个通过函数指针调⽤的函数。 如果你把函数的指针地址作为参数传递给另⼀个函数当这个指针被⽤来调⽤其所指向的函数 时被调⽤的函数就是回调函数。回调函数不是由该函数的实现⽅直接调⽤⽽是在特定的事件或条 件发⽣时由另外的⼀⽅调⽤的⽤于对该事件或条件进⾏响应。上一篇博客中写了一个简易的计算器int Add(int x, int y) { return x y; } int Sub(int x, int y) { return x - y; } int Mul(int x, int y) { return x * y; } int Div(int x, int y) { return x / y; } void menu() { printf(-------------------------------\n); printf(----- 1. add 2. sub -----\n); printf(----- 3. mul 4. div -----\n); printf(----- 0. exit -----\n); printf(-------------------------------\n); } void calc(int (*pf)(int, int)) { int x 0; int y 0; int r 0; printf(请输入2个操作数:); scanf(%d%d, x, y); r pf(x, y); printf(结果是: %d\n, r); } int main() { int input 0; do { menu(); printf(请选择:); scanf(%d, input); switch (input) { case 1: calc(Add); break; case 2: calc(Sub); break; case 3: calc(Mul); break; case 4: calc(Div); break; case 0: printf(退出计算器\n); break; default: printf(输入错误请输入0~4的值\n); break; } } while (input); return 0; }这里int (*pf)(int, int)作为calc函数的参数说白了回调函数就是将函数的地址作为新函数的参数以达到进行调用的目的通常可起到简化代码量的作用。2. qsortqsort函数原型void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*))qsort是基于快速排序实现可排序任意类型的数据1.void*指向数组中第一个要排序的对象转换为void*。2.size_t num数组中按基数指向的元素数。3.size_t size数组中每个元素的字节大小。4.int (*compar)(const void*,const void*) 函数指针指向一个比较两个元素的函数。其中comp函数的规则如下返回值含义0p1指向的元素小于p2指向的元素0p1指向的元素大于p2指向的元素0p1指向的元素等于p2指向的元素由此我们可得到以下代码需包含stdlib.h int comp(const void* p1, const void* p2)//void*无法解引用需要强制转换为int*类型 { //if (*(int*)p1 *(int*)p2) // return -1; //else if (*(int*)p1 *(int*)p2) // return 1; //else // return 0; return(*(int*)p1 - *(int*)p2); } int main() { int arr[10] { 9,8,7,6,5,4,3,2,1,0 }; int len sizeof(arr) / sizeof(arr[0]); int size sizeof(int); qsort(arr,len,size,comp); for (int i 0; i 10; i) { printf(%d , *(arr i)); } return 0; }如果想要降序排列return(*(int*)p2 - *(int*)p1);也可对结构体排序struct Stu { char name[20]; int age; }; int cmp_age(const void* p1,const void* p2)//年龄升序 { return (*(struct Stu*)p1).age - (*(struct Stu*)p2).age; } int main() { struct Stu arr[] { {zhangsan,18},{lisi,25},{wangwu,15} }; int sz sizeof(arr) / sizeof(arr[0]); qsort(arr, sz, sizeof(arr[0]), cmp_age); for (int i 0; i sz; i) { printf(%d , arr[i].age); } return 0; }还可通过name进行排序等后面介绍strcmp函数后再实现。关于结构体其他的知识后面也会写博客介绍3. qsort函数的模拟实现使⽤回调函数模拟实现qsort采⽤冒泡的⽅式首先给出冒泡排序的基础代码void bubble_sort(int* arr, int sz) { int flag 1; for (int i 0; i sz - 1; i) { for (int j 0; j sz - i - 1; j) { if (arr[j] arr[j 1]) { int tmp arr[j]; arr[j] arr[j 1]; arr[j 1] tmp; flag 0; } } if (flag) return; } }仿造sqsort给出函数原型void my_qsort(void* base, size_t len, size_t size, int(*cmp)(const void* p1, const void* p2))主体还是两个for循环来控制排序的次数for (int i 0; i len - 1; i) { for (int j 0; j len - i - 1; j) { ....... } } }下面是否进行该次排序的条件可通过comp函数实现int comp(const void* p1, const void* p2) { return *(int*)p1 - *(int*)p2; }冒泡排序的交换可通过swap函数实现void swap(char* buf1, char* buf2, size_t size) { for (int i 0; i size; i) { char tmp *buf1; *buf1 *buf2; *buf2 tmp; buf1; buf2; } }注意由于这里是char* 类型的指针所以交换时只能一个字节一个字节的进行交换看图完整代码如下int comp(const void* p1, const void* p2) { return *(int*)p1 - *(int*)p2; } void swap(char* buf1, char* buf2, size_t size) { for (int i 0; i size; i) { char tmp *buf1; *buf1 *buf2; *buf2 tmp; buf1; buf2; } } void my_qsort(void* base, size_t len, size_t size, int(*cmp)(const void* p1, const void* p2)) { for (int i 0; i len - 1; i) { for (int j 0; j len - i - 1; j) { if (cmp((char*)base j * size, (char*)base j * size 1)) { swap((char*)base j * size, (char*)base (j 1) * size, size); } } } }这段代码只是为了帮我们理解qsort函数,实际操作直接使用qsort函数即可