C/C++函数指针总结之二:C函数指针的使用.
2012-01-16 20:38
253 查看
上一篇总结了函数指针的定义、赋值等基本知识。那么函数指针用在哪儿呢?如果象上一篇的例子里面那样用,纯粹就是脱裤子放p,直接使用函数好了。函数指针最经典的应用就是回调了,就是将一个函数1指针作为参数传给另外一个函数2,在这个函数2中就可以用传入的函数指针来调用那个函数。
我们先看看qsort和bsearch吧。假设我从数据库的某个千万以上级别表里面取了几10万条记录需要做运算,现在想根据某(几)个字段排个序,由于这些字段没有索引,若直接用数据库的order
by可能会死的很惨,那就用qsort,多方便啊,写个排序函数就行了。
在我目前使用的c-tree数据库的C/C++API里面,提供了一些事件的处理机制。这个处理机制也是通过回调函数的方式来实现的。你只要给某个事件登记一个你自定义的函数(当然需要符合要求,就跟qsort的排序函数需要返回大于0,小于0和等于0一样)的指针,那么在数据库发生该事件的时候就会自动调用你的函数。这相当于在C/C++这一层提供了SQL里面的触发器功能。例如CTDB_ON_RECORD_AFTER_WRITE这个事件,就可以在某个表写入记录时做一些事情。
在某些硬件提供的API里面也经常会用回调函数。只要调用其提供的相关接口函数注册自定义的回调函数,在硬件内部发生某个事件时(如报告某类数据),相应的回调函数就会被调用。在回调函数内,你就可以得到硬件内部返回出来的消息和数据。
我们先看看qsort和bsearch吧。假设我从数据库的某个千万以上级别表里面取了几10万条记录需要做运算,现在想根据某(几)个字段排个序,由于这些字段没有索引,若直接用数据库的order
by可能会死的很惨,那就用qsort,多方便啊,写个排序函数就行了。
#include <stdlib.h> #include <stdio.h> #include <string.h> /*记录结构*/ typedef struct { long long id; time_t creation_time; char code[3]; } TableStruct;针对这个结构定义一个排序函数:
/*排序函数,按term_time降序,code升序 */ int cmp(const void*p1, const void *p2){ const TableStruct *q1 = (const TableStruct *)p1; const TableStruct *q2 = (const TableStruct *)p2; if(q1->creation_time < q2->creation_time) return 1; else if(q1->creation_time > q2->creation_time) return -1; else return strcmp(q1->code, q2->code); }写个模拟的数据加载函数:
int LoadSomeData(TableStruct **ppData){ int i, n = 10; *ppData = (TableStruct*) malloc(sizeof(TableStruct)*n); for(i=0; i<10; i++){ ((*ppData)+i)->id = i+1; ((*ppData)+i)->creation_time= 1234567890+i%5; sprintf(((*ppData)+i)->code, "A%d", i%10); } return n; }主测试程序:
int main() { /*存放数据的指针*/ TableStruct *pData = NULL; /*从数据库加载相关记录,返回值为加载的记录数*/ int n = LoadSomeData(&pData); if(n<=0){ return 0; } else{ /*gcc里面的函数原型: void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)); 第一个参数是待排序的数据首地址, 第二个参数是待排序的数据中有多少个元素 第三个参数是每个元素的大小 第四个参数就是比较函数的指针 */ qsort((void*)pData, n, sizeof(TableStruct), cmp); //or &cmp } int i; for(i=0; i<n; i++){ printf("id=%lld\n", (pData+i)->id); printf("creation_time=%ld\n", (pData+i)->creation_time); printf("code=%s\n", (pData+i)->code); } TableStruct criterion; /*只需要填充需要比较的字段*/ criterion.creation_time = 1234567890; strcpy(criterion.code,"A5"); TableStruct* pResult = (TableStruct*) bsearch((const void*)&criterion, (const void*)pData, n, sizeof(TableStruct), cmp); if(pResult == NULL){ printf("Not found"); } else{ /*found*/ printf("id = %lld\n", pResult->id); } free(pData); return 0; }
在我目前使用的c-tree数据库的C/C++API里面,提供了一些事件的处理机制。这个处理机制也是通过回调函数的方式来实现的。你只要给某个事件登记一个你自定义的函数(当然需要符合要求,就跟qsort的排序函数需要返回大于0,小于0和等于0一样)的指针,那么在数据库发生该事件的时候就会自动调用你的函数。这相当于在C/C++这一层提供了SQL里面的触发器功能。例如CTDB_ON_RECORD_AFTER_WRITE这个事件,就可以在某个表写入记录时做一些事情。
//定义回调函数 CTDBRET ctdbDECL onRecordAfterWrite(CTHANDLE Handle){ … } //在相关地方注册回调函数 if (ctdbSetCallback(hRecord, CTDB_ON_RECORD_AFTER_WRITE, OnRecordAfterWrite) != CTDBRET_OK) printf("ctdbSetCallback failed\n");
在某些硬件提供的API里面也经常会用回调函数。只要调用其提供的相关接口函数注册自定义的回调函数,在硬件内部发生某个事件时(如报告某类数据),相应的回调函数就会被调用。在回调函数内,你就可以得到硬件内部返回出来的消息和数据。
相关文章推荐
- 自己关于指针在函数中使用的理解和总结
- C语言中函数指针的三种使用方法总结
- 使用指针作为函数返回值和参数的问题总结
- c总结9--- 二级指针使用三种模型之二(二级指针2)
- 【实习记】2014-08-27堆排序理解总结+使用typedef指代函数指针
- python3 join函数使用总结
- 函数指针2017/12/2C语言学习内容总结
- vue.js中生命周期与相关函数的使用总结
- 使用void指针给函数传递不同的数据类型
- 指向函数的指针的使用
- 指针数组的使用总结
- fopen\fread\fwrite\fscanf\fprintf\fseek\feof\rewind\fgets\fputc等系列函数使用总结
- C基础知识-函数指针以及使用
- typedef&nbsp;和函数指针问题深入总结
- Oracle分析函数使用总结
- 单链表的操作和函数指针的基本使用
- 函数调用缺少参数列表;请使用“&****Dlg::getThread”创建指向成员的指针”--多线程函数调用
- 【归纳总结】函数指针和回调函数
- PHP学习笔记——使用数组的内部指针控制函数遍历数组
- 函数指针使用的一点理解