1.代码debug
//输入"help"程序都返回为"This is a wrong cm";
//输入"version""quit"程序返回正常;
//设置断点,检查输入"quit"时指针p为空指针的原因;
//输入"quit"程序后,调用FIndCmd获取p值,而FindCmd又调用SearchLinkTableNode;
//SearchLinkTableNode的逻辑中,while内使用回调函数Condition判断用户指令是否正确;
//while循环判断存在异常,当pNode=pLinkTable->tail时,程序直接return NULL;
//根据menu.c中的InitMenuData,我们可以知道"quit"指令是pLinkTable的第三个节点;
//结合上述代码流程,这就解释了为什么输入"version""help"都没有问题,而"quit"指令异常;
//修改代码后重新测试。
2.callback接口运行机制、callback设计方案
什么是callback?
把一段可执行的代码像参数传递那样传给其他代码,而这段代码会在某个时刻被调用执行,这就叫做回调。
如果代码立即被执行就称为同步回调,如果在之后晚点的某个时间再执行,则称之为异步回调。
举例定义:函数A()作为函数B(int (* A))的函数指针参数,在函数B中会调用函数A的方法,函数A是回调函数。
为什么需要callback?
使用callback可以的好处和作用就是解耦,结合callback的实际开发场景,我们可以更好的理解它。
参考博文:https://www.cnblogs.com/arsh/p/11283806.html

A(int m, int n, bool * f(m,n)) 1. 既然是函数的参数,就具备了扩展性和代码重用的作用,因为形参不变,实参是可变的。所以调用时,可以A(x,y,B),也可以A(x,y,C),这里B和C都是回调函数,有点像虚函数。(B和C可以实现不同的功能,或以不同的方式实现) ----场景:代码重用。A(x, y, isGreater), A(x, y , isSmaller) 2. 在定义A()时,甚至不需要知道实际的被调函数的名字,只要知道这个接口的格式,即参数,返回值,实现功能。所以甚至在确定被调函数如何实现之前,只要约定好接口和功能,就可以进行A()的定义工作。(实现相同的功能) ----场景:框架编程,并行工作。业务流程步骤编排(不管具体实现)。 A(bool * f()) 3. 甚至被调函数f()到底实现什么功能,也是可以不定义的。只是在A里面规定好条件触发,将具体做什么的决定权交给用户。 ----场景:事件,通知。 我猜OnTimer()应当就是一个回调函数,开放给用户自定义动作。整个定时器的机制已经是预定义好的。 main函数其实也是。都是事件机制。 4. 结合多线程异步使用。 ----场景:工作继续进行,主函数先结束。 void A(url, call) { 开启url线程,传入call 函数本身返回. } 5.结合延迟函数。 void A(call) { setTimeout(call, 10000) 函数本身返回. }
callback运行机制以及实例分析。
//自定义的回调函数,用于判断用户输入的指令是否正确;
int SearchCondition(tLinkTableNode * pLinkTableNode) { tDataNode * pNode = (tDataNode *)pLinkTableNode; if(strcmp(pNode->cmd, cmd) == 0) { return SUCCESS; } return FAILURE; }
//定义函数SearchLinkTableNode,带有callback接口;
tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode)) { if(pLinkTable == NULL || Conditon == NULL) { return NULL; } tLinkTableNode * pNode = pLinkTable->pHead; while(pNode != NULL) { if(Conditon(pNode) == SUCCESS) { return pNode; } pNode = pNode->pNext; } return NULL; }
//将SearchCondition作为函数指针参数提供给函数SearchLinkTableNode;
//函数SearchLinkTableNode执行Condition(pNode)时会调用函数SearchCondition。
tDataNode* FindCmd(tLinkTable * head, char * cmd) { return (tDataNode*)SearchLinkTableNode(head,SearchCondition); }
callback接口设计方法。
callback无参数接口设计
int A(){ return 0; } int B(int (*Callback)()){ return Callback();
}
int main(){
B(A);
return 0;
}
callback多参数接口设计
int A(int a, int b){ return a+b; } int B(int a, int b, int (*Callback)(int, int)){ return Callback(a, b); } int main(){ B(1,2,A); return 0; }