反弹表达式是借助表达式指针做表达式参数,同时实现的一类初始化监督机制,年度计划的同时实现者,能不晓得甚么这时候被初始化。
反弹监督机制基本原理:
当具体内容该事件出现时,初始化者透过表达式指针初始化具体内容表达式。
反弹监督机制的将初始化者和被调表达式合二为一,二者彼此之间倚赖。
各项任务的同时实现和各项任务的初始化能同时实现松谐振(提早展开USB的PCB和结构设计)。
看下列示例:
#include <iostream> using namespace std; int add(int a, int b); void libfun(int (*pDis)(int a, int b)); int main(void) { int (*pfun)(int a, intb); pfun = add; libfun(pfun);return 0; } int add(int a, int b) { return a + b; } int minus(int a, int b) { return a – b; } void libfun(int (*pDis)(int a, int b)) { int a, b; a = 1; b = 2; int c = add(a,b); //直接初始化add表达式 c = pDis(a, b); printf(“%d”, c); //透过表达式指针做表达式参数,间接初始化add表达式 //思考这样写pDis(a, b)有甚么好处? }假设要同时实现减法呢?现在这几个表达式是在同一个文件当中,能直接在
int libfun(int (*pDis)(int a, int b))
中修改,假设libfunc()是一个库中的表达式,你就只能使用表达式指针的反弹监督机制了,透过表达式指针参数将外部表达式地址传入来同时实现初始化。
当然,表达式 add()或minus() 的代码作了修改,也不必改动库的代码,就能正常同时实现初始化。
最重要的是,即使将add换成另一个表达式,也不需要修改libfun(),只需在初始化时将其表达式指针参数使用不同的实参就行了。这就是低谐振的思想,便于程序的维护和升级。
再看一个例子:
#include <iostream> using namespace std; bool lesser(int a, int b); bool greater(inta,int b); void libSwap(bool (*pDis)(int a, int b)); // 透过表达式直接来初始化lesser()或greater()表达式 void libSwap(); // 直接在表达式体内初始化lesser()或greater()表达式 int main(void) { libSwap(lesser); //libSwap(greater); libSwap(); while(1); return 0; } bool greater(int a, int b) { return a > b; } bool lesser(int a, int b) { return a < b; } void libSwap(bool (*pDis)(int a, int b)) //透过表达式指针做表达式参数,间接初始化add表达式 { int a = 5, b = 7; if(pDis(a, b)) { inttmp = a; a = b; b = tmp; }cout<<a<<” “<<b<<endl; } void libSwap() //直接在表达式体内初始化lesser()或greater()表达式 { inta =5, b = 7; if(lesser(a,b)) //if(greater(a,b)) { int tmp = a; a = b; b = tmp; } cout<<a<<” “<<b<<endl; }上列假设libSwap()是库表达式。库使用者在main()中初始化
void libSwap(bool (*pDis)(int a, int b))
此表达式有一个表达式指针,需要提供表达式供其使用,此时库使用者编写greater()、lesser(),这两个表达式库使用者并不直接初始化,而是由libSwap()去初始化。greater()、lesser()这种表达式就称为反弹表达式,整个结构设计监督机制就是反弹表达式初始化监督机制。
所谓反弹,就是客户程序C初始化服务程序S中的某个表达式s(),然后S又在某个这时候反过来初始化C中的某个表达式c(),对于C来说,这个c()便叫做反弹表达式。例如Win32下的窗口过程函数就是一个典型的反弹表达式。
一般说来,C不会自己初始化c(),c()提供c()的目的就是让S来初始化它,而且是C不得不提供。由于S并不晓得C提供的c()叫甚名谁,所以S会约定c()的USB规范(表达式原型),然后由C提早透过S的一个表达式r()告诉S自己将要使用c()表达式,这个过程称为反弹表达式的注册,R称为注册表达式。
在框架中,定义表达式指针,相当于提早指定了一套协议USB。
对于排序表达式,如果想用同一个排序表达式来实现升序或降序排列,初始化时不修改此表达式的排序逻辑,能考虑使用表达式指针来初始化反弹表达式,而stdlib.h库中的qsort()表达式即是如此来同时实现这一逻辑的:
#include <stdio.h> #include <stdlib.h> int compare(int a, int b) // 用于bubbleSort()的反弹表达式 { return a-b; //return b-a; } int cmp(const void* a, const void* b) // 用于库表达式qsort() { return (*((int*)a) – *((int*)b)); //return (*((int*)b) – *((int*)a)); } void bubbleSort(int arr[], int n, int (*compare)(int,int)) { // 只需更改表达式指针指向的反弹表达式,即可同时实现升序或降序排列 for(int i=0; i<n; i++)for(int j=0;j<n-i-1; j++) if(compare(arr[j],arr[j+1])>0) { int tmp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = tmp; } } void arrOutput(int arr[], int n) { for(int i=0;i<n; i++) printf(“%d “,arr[i]);printf(“\n”); } int main() { int arr[] = {3,2,1,5,4}; int n = sizeof(arr)/sizeof(arr[0]); bubbleSort(arr,n,compare); arrOutput(arr,n);int arr2[] = {3,2,1,5,4}; qsort(arr2,n,sizeof(int),cmp); arrOutput(arr2,n);while(1); return 0; } /* 1 2 3 4 5 1 2 3 4 5 */-End-