上次我们说到了函数指针,对于函数指针大家还不太清楚的参考,指针进阶(一)http://t.csdn.cn/z5cjM
数组是存放相同类型的空间,前面我们已经学习了指针数组
int* arr[10] 每个元素是int*
那么我们把函数的地址存放到一个数组中,这个数组我们就称为函数指针数组,函数指针数组怎么书写呢?
一个·函数指针 int(*pa)(int ,int)=函数地址
多个函数指针就是函数指针数组了
上面是通过伪代码的形式呈现,那么在实际应用有·什么用呢,我们举一个例子
设计一个计算器,程序不难
#include 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);
}int main()
{//int (*pa)(int, int) = 函数名;//int (*ppa[5])(int, int) = { 函数名,函数名,函数名,函数名,函数名 };int x = 0;int y = 0;int ret = 0;int input = 1;int(*pa[5])(int ,int ) = { NULL,add,sub,mul,div };while (input){printf("***************************************\n");printf("**** 1.add 2.sub *********\n");printf("**** 3.mul 4.div *********\n");printf("**** 0.结束 *********\n");printf("***************************************\n");printf("请输入->\n");scanf("%d", &input);if (input >= 1 && input <= 4){printf("请输入操作数->\n");scanf("%d %d", &x, &y);ret = (*pa[input])(x, y);}else{printf("输入错误,重新输入\n");}printf("%d\n", ret);}return 0;
}
指向函数指针数组的指针也就是一个指针,这个指针 指向 函数指针数组
就如上面的函数指针数组:int(*pa[5])(int ,int ) = { NULL,add,sub,mul,div };
我们怎么写一个指针指向这个函数指针数组
回调函数就是一个通过函数指针的调用的函数
如果你把函数的指针(地址)作为参数传递给另外的函数,当这个指针被用来调用其所指向的函数时,我们就说这个是回调函数
库函数中有一个函数qsort
qsort函数的作用是可以进行数据的排序
首先我们要了解qsort函数,通过cplusplus网
看不懂不要紧,下面也有例子
说那么多还是看实例吧
//从小到大排
#include
#include
int sort_int(const void*e1, const void*e2)
{return *(int*)e1 - *(int*)e2;
}
int main()
{int arr[] = { 5,6,7,8,9,0,1,2,3,4 };qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(arr[0]), sort_int);int ret = sizeof(arr) / sizeof(arr[0]);int i = 0;for (i = 0; i < ret; i++){printf("%d ", arr[i]);}return 0;
}
有人说我要从大到小怎么办
#include
#include
int sort_int(const void*e1, const void*e2)
{return *(int*)e2 - *(int*)e1;
}
int main()
{int arr[] = { 5,6,7,8,9,0,1,2,3,4 };qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(arr[0]), sort_int);int ret = sizeof(arr) / sizeof(arr[0]);int i = 0;for (i = 0; i < ret; i++){printf("%d ", arr[i]);}return 0;
}
将return 里面的两个相减数交换位置就好了
整型的排序我们会了,字符型,结构体的排序呢
字符型
#include
#include
#include
int sort_char(const void* e1, const void* e2)
{return *(char*)e1 - *(char*)e2;
}
int main()
{char arr[] = "acbed";qsort(arr, strlen(arr), sizeof(arr[0]), sort_char);int ret = sizeof(arr) / sizeof(arr[0]);printf("%s", arr);return 0;
}
//结构体
#include
#include
#include struct str
{char name[20];int age;
};
int sort_struct(const void* e1, const void* e2)
{return ((struct str*)e1)->age - ((struct str*)e2)->age;
}
int main()
{struct str s[] = { {"xiao ming",23},{"li hua",20},{"wang wu",21} };qsort(s, sizeof(s)/sizeof(s[0]), sizeof(s[0]), sort_struct);return 0;
}
那么qsort函数是怎么实现的,我们在之前学过冒泡排序,就是排整型数据的,qsort内部是使用快速排序的,今天我们利用冒泡排序的思想模拟qsort函数
先回忆一下冒泡排序
#include 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 - i - 1; j++){if (arr[j] > arr[j + 1]){int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}}
}int main()
{int arr[] = { 1,2,3,4,0,8,9,7,6,5 };int sz = sizeof(arr) / sizeof(arr[0]);bubble_sort(arr, sz);int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}
但是冒泡排序只能排整型,不能排字符型,也不能排结构体
我们设计一个兼容可以排序整型,又可以排字符型和结构体的呢
模拟qsort的思想,利用冒泡的形式
#include
#include
#include struct str
{char name[20];int age;};int sort_jud_int(void* e1, void* e2)
{return *(int*)e1 - *(int*)e2;
}int sort_jud_char(void* e1, void* e2)
{if (*(char*)e1 > *(char*)e2)return 1;elsereturn -1;
}int sort_jud_struct_age(void* e1, void* e2)
{return ((struct str*)e1)->age - ((struct str*)e2)->age;
}int sort_jud_struct_name(void* e1, void* e2)
{return strcmp(((struct str*)e1) ->name,((struct str*)e2) ->name);
}void swap(char* base1, char* base2, int width)
{int i = 0;for (i = 0; i < width; i++){char tmp = *base1;*base1 = *base2;*base2 = tmp;base1++;base2++;}
}void my_qsort(void* base, int sz, int width,int (*pa)(void*,void*))
{int i = 0;for (i = 0; i < sz - 1; i++){int j = 0;for (j = 0; j < sz - i - 1; j++){if (pa((char*)base + j * width, (char*)base + (j + 1) * width) > 0){swap((char*)base + j * width, (char*)base + (j + 1) * width, width);}}}
}void test1()
{int arr[] = { 5,6,7,8,9,0,1,2,3,4 };int ret = sizeof(arr) / sizeof(arr[0]);my_qsort(arr, ret, sizeof(arr[0]), sort_jud_int);int i = 0;for (i = 0; i < ret; i++){printf("%d ", arr[i]);}}void test2()
{char arr[] = "acdeba";my_qsort(arr, strlen(arr), sizeof(arr[0]), sort_jud_char);puts(arr);
}void test3()
{struct str s[3] = { {"zhangsan",23},{"lisi",20},{"wangwu",19} };int ret = sizeof(s) / sizeof(s[0]);//my_qsort(s, ret, sizeof(s[0]), sort_jud_struct_age);my_qsort(s, ret, sizeof(s[0]), sort_jud_struct_name);
}int main()
{//test1();//整型//test2();//字符串test3();//结构体return 0;
}
整体代码是上述的,是怎么实现的,我们一步一步剖析
上面是对一个大局部进行剖析,字符型和结构体的大同小异
我们理一理我们设计的my_qsort函数
那么谁是回调函数呢
有概念说,把函数的指针作为参数传递给另外的函数,当这个指针用来调用其所指向的函数的时候,我们就是说这个是回调函数
这样看来我们可以称sort_jud_int函数为回调函数了
回调函数的使用多种多样,结合指针,我们可以玩出多种多样的花样
下一篇:[cpp进阶]C++智能指针