C/C++回调函数

2023-09-06 0 371

7.1 反弹表达式

反弹表达式是两个透过表达式操作符调用的表达式。假如你把表达式的操作符(门牌号)做为HTA给另两个表达式,当这个操作符被用以调用其所对准的表达式时,他们就说这是反弹表达式。反弹表达式并非由该表达式的同时实现方直接调用,而是在某一的该事件或前提出现时由另外的另一方调用的,用作对该该事件或前提展开积极响应。

7.1.1 监督机制

⑴表述两个反弹表达式;

⑵提供更多表达式同时实现的另一方在调用的这时候,将反弹表达式的表达式操作符注册登记给分配器;

⑶当某一的事件或前提出现的这时候,分配器采用表达式操作符调用反弹表达式对该事件展开处置。

7.1.2 意义

即使能把分配器与被分配器合二为一,所以分配器不重视谁是被分配器。它只需晓得存在两个具备某一蓝本和限制前提的被调用表达式。简而言之,反弹表达式是容许使用者把需要调用的表达式的操作符做为HTA给两个表达式,以期该表达式在处置相近该事件的这时候能灵巧的采用不同的方式。

想晓得反弹表达式在实际甚么作用?先假定有这样一种情况:他们要撰写两个库,它提供更多了某些次序演算法的同时实现(如冒泡次序、快速次序、shell次序、shake次序等等),为了能让库更加通用型,不想在表达式中内嵌次序方式论,而让采用者来同时实现适当的方式论;或者,能让库可用作多种正则表达式(int、float、string),此时,该咋办呢?能采用表达式操作符,并展开反弹。

反弹可用作通告监督机制。比如,有时要在A流程中增设两个计时,每到一定时间,A流程会得到适当的通告,但通告监督机制的同时实现者对A流程不屑一顾。那么,就需两个具备某一蓝本的表达式操作符展开反弹,通告A流程该事件已经出现。实际上,API采用两个反弹表达式SetTimer()来通告计时。假如没有提供更多反弹表达式,它还会把两个最新消息发往流程的最新消息堆栈。

另两个采用反弹监督机制的API表达式是EnumWindow(),它隐式萤幕上所有的第二层询问处,每个询问处都能透过它调用另两个流程提供更多的表达式,并传达询问处的处置流程。比如:假如被分配器回到两个值,就继续展开插值;不然,选择退出。EnumWindow()并不重视被分配器在何方,也不重视被分配器用它传达的处置流程做了甚么,它只重视codice,即使如前所述codice,它将拒绝执行或选择退出。

不能不说,反弹表达式是承继自C语言的。在C++中,应只在与C标识符建立USB或与已有的反弹USB关系密切时,才采用反弹表达式。除了前述,在C++别列济夫采用交互式方式或仿表达式(functor),而并非反弹表达式。

7.1.3 说明

你到两个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。在这个例子里,你的电话号码就叫反弹表达式,你把电话留给店员就叫登记反弹表达式,店里后来有货了叫做触发了反弹关联的该事件,店员给你打电话叫做调用反弹表达式,你到店里去取货叫做积极响应反弹该事件。

https://www.cnblogs.com/ioleon13/archive/2010/03/02/1676621.html

7.2 用表达式操作符做为表达式的codice

在操作符表达式里面,有这样一类表达式,它们也回到操作符型数据(门牌号),但是这个操作符并非对准int、char之类的基本类型,而是对准表达式。对于初学者,别说写出这样的表达式声明,是看到这样的写法也是一头雾水。比如,下面的语句:

int (*ff(int))(int *, int);

他们用上面介绍的方式分析一下,ff首先与后面的“()”结合,即:

int (*(ff(int)))(int *, int); // 用括号将ff(int)再括起来

也就意味着,ff是两个表达式。

接着与前面的“*”结合,说明ff表达式的codice是两个操作符。然后再与后面的“()”结合,也是说,该操作符对准的是两个表达式。

这种写法确实让人非常难懂,以至于一些初学者产生误解,认为写出别人看不懂的标识符才能显示自己水平高。而事实上恰好相反,能否写出通俗易懂的标识符是衡量流程员是否优秀的标准。一般来说,用typedef关键字会使该声明更简单易懂。在前面他们已经见过:

int (*PF)(int *, int);

也是说,PF是两个表达式操作符“变量”。当采用typedef声明后,则PF就成为了两个表达式操作符“类型”,即:

typedef int (*PF)(int *, int);

这样就表述了codice的类型。然后,再用PF做为codice来声明表达式:

PF ff(int);

下面将以流程清单1为例,说明用表达式操作符做为表达式的codice的用法。当流程接收使用者输入时,假如使用者输入d,则求数组的最大值,假如输入x,则求数组的最小值,假如输入p,则求数组的平均值。

#include<stdio.h>

#include<assert.h>

double UnKnown(double *dbData, int iSize); // 未知演算法

double GetAverage(double *dbData, int iSize); // 求平均值

double GetMax(double *dbData, int iSize); // 求最大值

double GetMin(double *dbData, int iSize); // 求最小值

typedef double (*PF)(double *dbData, int iSize); //表述表达式操作符类型

PF GetOperation(char c) ;

int main(void)

{

double dbData[]={3.1415926, 1.4142, -0.5,999, -313, 365};

int iSize = sizeof(dbData)/sizeof(dbData[0]);

char c;

printf(“Please input the Operation :\n”);

c = getchar();

printf(“result is %lf\n”,GetOperation(c)(dbData,iSize));// 透过表达式操作符调用表达式

}

PF GetOperation(char c) // 根据字符得到操作类型,回到表达式操作符

{

switch(c)

{

case d:

return GetMax;

case x:

return GetMin;

case p:

return GetAverage;

default:

return UnKnown;

}

}

double GetMin(double *dbData, int iSize) // 求最小值

{

double dbMin;

int i;

assert(iSize > 0);

/*

void assert( int expression );

assert的作用是现计算表达式 expression ,假如其值为假(即为0),

那么它先向stderr打印一条出错信息,然后透过调用 abort 来终止流程运行。

此时流程就不会继续往下执行

*/

dbMin = dbData[0];

for(i = 1; i < iSize; i++)

{

if(dbMin > dbData[i])

{

dbMin = dbData[i];

}

}

return dbMin;

}

double GetMax(double *dbData, int iSize) // 求最大值

{

double dbMax;

int i;

assert(iSize > 0);

dbMax = dbData[0];

for(i = 1; i < iSize; i++)

{

if(dbMax < dbData[i])

{

dbMax = dbData[i];

}

}

return dbMax;

}

double GetAverage(double *dbData, int iSize) // 求平均值

{

double dbSum = 0;

int i;

assert(iSize > 0);

for(i = 0; i < iSize; i++)

{

dbSum += dbData[i];

}

return dbSum / iSize;

}

double UnKnown(double *dbData, int iSize) // 未知演算法

{

return 0;

}

上述流程中前面4个表达式分别同时实现求最大值、最小值、平均值和未知演算法,然后同时实现了GetOperation表达式。这个表达式根据字符的codice同时实现上面4个表达式。它是以表达式操作符的形式回到的,从后面的main表达式的GetOperation(c)(dbData, iSize)能看出,透过这个操作符能调用表达式。

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务