C语言中指向函数的指针应用

在C语言中,指针(特别是指向函数的指针)是一个让初学者非常头痛的概念,但是这也是C语言最灵活的特性,如果把指针用好了的话,就可以方便的解决很多复杂的问题,下面我就谈谈我的一点体会,

我最近在开发一个试题库的管理软件,在写其中的《题库信息》这个模块的时侯,其中的分类统计有两种方式:按某种属性的总分值统计和按它所有试题的数量统计,那么就有两个不同的统计函数SumByScore和SumByCount,这样在程序中凡是要统计的地方就得判断要用哪个函数:

  if(按分数统计) ......SumByScore(......)......; else ......SumByCount(......)......; 

若一处两处还不要紧,但多了就很麻烦了,比如说在我的程序中就要对5种不同的情况进行统计,就显得很不爽了,那么有没有简单一点的办法呢?后来我就用指向函数的指针解决了这个问题,我的思路是这样的:

因为我的两个函数的参数类型都是相同的,也就是数据库的Filter,用的是AnsiString类型,并且返回类型都是int,那么我就定义一个指向函数的指针int (*SumData)(AnsiString);然后在需要进行统计之前根据选择让这个指针指向相应的函数,在以后统计时就用(*SumData)(参数)就可以了,即:

  int (*SumData)(AnsiString); SumData=(按分数统计)?SumByScore:SumByCount; ......(*SumData)(参数)......; 

可能有人要问,如果参数不同或返回类型不同怎么办?如果返回类型不同,我想也用不着用这样做了;如果是参数不同,可以通过一个中间转换来完成,例如:

  int x1(int,char*); int y2(char*,int); //--------------- inline int x1cvr(int m,char* n,char* j,int k) { return x1(m,n); } //---------------- inline int x2cvr(int m,char* n,char* j,int k) { return x2(j,k); } //------------------ main() { int (*x)(int,char*,char*,int); x=(条件)?x1:x2; x(1,"1234","123",2); } 

不知家发现了什么?是不是一种方法多种实现?看来用指向函数的指针也可以实现多态性。

附:我的程序中的相关代码(C++Builder 4.0)


  //根据指定的FILTER对题库进行分值统计 int SumTable1(AnsiString filter) { AnsiString oldFilter=fmCount->tabTk->Filter; bool oldFiltered=fmCount->tabTk->Filtered; long sum=0; fmCount->tabTk->Filter=filter; fmCount->tabTk->Filtered=true; //-------------------------------------------- fmCount->tabTk->First(); while(!fmCount->tabTk->Eof) { sum+=fmCount->tabTk->FieldByName("Score")->AsInteger; fmCount->tabTk->Next(); } //-------------------------------------------- fmCount->tabTk->Filter=oldFilter; fmCount->tabTk->Filtered=oldFiltered; return sum; } //--------------------------------------------------------------------------- //根据指定的FILTER对题库进行题量统计 int CountTable1(AnsiString filter) { AnsiString oldFilter=fmCount->tabTk->Filter; bool oldFiltered=fmCount->tabTk->Filtered; long sum=0; fmCount->tabTk->Filter=filter; fmCount->tabTk->Filtered=true; sum=fmCount->tabTk->RecordCount; fmCount->tabTk->Filter=oldFilter; fmCount->tabTk->Filtered=oldFiltered; return sum; } //----------------------------------------------------------------------------- void __fastcall TfmCount::btTeeClick(TObject *Sender) { int SumTable1(AnsiString filter); int CountTable1(AnsiString filter); //清空图表 this->Series1->Clear(); int i; int (*CountType)(AnsiString); //根据统计类型选相应的统计函数 CountType=(rdGrpCountType->ItemIndex==1)?CountTable1:SumTable1; switch (rdGrpItem->ItemIndex) { //按章节统计 case 0: { for(i=1;i<=tabKm->FieldByName("MostChapter")->AsInteger;i++) { AnsiString tmpFilter="Chapter="; tmpFilter+=AnsiString(i); Series1->AddBar((*CountType)(tmpFilter), AnsiString("第")+AnsiString(i)+AnsiString("章"), clTeeColor); } break; } //按题型统计 case 1: { tabTx->First(); while(!tabTx->Eof) { AnsiString tmpFilter="TestNumber="; tmpFilter+=tabTx->FieldByName("TestNumber")->AsString; Series1->AddBar((*CountType)(tmpFilter), tabTx->FieldByName("TestQuestions")->AsString, clTeeColor); tabTx->Next(); } break; } //按难度统计 case 2: { char strNd[5][5]={"容易","偏易","一般","偏难","困难"}; for(i=1;i<=5;i++) { AnsiString tmpFilter="Difficulty="; tmpFilter+=AnsiString(i); Series1->AddBar((*CountType)(tmpFilter), strNd[i-1], clTeeColor); } break; } //按档次统计 case 3: { Series1->AddBar((*CountType)("Level=/'一般/'"), "一般", clTeeColor); Series1->AddBar((*CountType)("Level=/'重点/'"), "重点", clTeeColor); break; } //按三基统计 case 4: { Series1->AddBar((*CountType)("ThreeBasic=/'基本知识/'"), "基本知识", clTeeColor); Series1->AddBar((*CountType)("ThreeBasic=/'基本理论/'"), "基本理论", clTeeColor); Series1->AddBar((*CountType)("ThreeBasic=/'基本技能/'"), "基本技能", clTeeColor); break; } } } //--------------------------------------------------------------------------- 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值