找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 17147|回復(fù): 3
收起左側(cè)

C語言回調(diào)函數(shù)熟練---使用方法(構(gòu)建程序框架方便好用)

[復(fù)制鏈接]
ID:71477 發(fā)表于 2015-1-1 19:40 | 顯示全部樓層 |閱讀模式
通俗點(diǎn)不行嗎?啊,不行嗎?老外把國(guó)人玩的都不是人了。國(guó)人還自己玩自己。非把一個(gè)簡(jiǎn)單的東西復(fù)雜化。叫那么難理解!窩里斗。。。。。。典型!。。。。。!
不說那么復(fù)雜的,誰是狗屎,豬屎。就說怎么用回調(diào)。
使用步驟:
1.寫一個(gè)函數(shù)A,A里面有一個(gè)參數(shù)是個(gè)指針函數(shù) 比如: int shao(int a,int (*Pcall)(void *p))
2.有個(gè)指針函數(shù)參數(shù),那他要指向一個(gè)函數(shù),OK,寫一個(gè)符合格式的函數(shù)B 比如 int CaoDan(int c)
3.使用A函數(shù)吧,參數(shù)賦值后,指針指向了一個(gè)函數(shù)地址,不就調(diào)用了嗎 比如 shao(36,CaoDan);
說明:A通過指針調(diào)用了B函數(shù),函數(shù)執(zhí)行語句里面,要用到指針才行啊。不然,光指向了。有個(gè)屁用。!
int shao(int a,int (*Pcall)(void *p))
{
    int PA;
    int PS;
    (*Pcall)(a); //指針函數(shù)的參數(shù)賦值,就看你了。想賦值誰都行。
    (*Pcall)(PS);
    (*Pcall)(PA);  
}
void main()
{
    shao(3,AFuc);//指向具體函數(shù)AFunc首地址
    shao(5,BFuc);
}
完畢,就是這么用的。
簡(jiǎn)單說:函數(shù)參數(shù)里有函數(shù)指針,指針指向的是函數(shù)地址,不是變量地址。這樣,函數(shù)你就可以隨便寫,都可以用這個(gè)回調(diào)函數(shù)當(dāng)一個(gè)參數(shù)來調(diào)用,多方便。程序通用性就更強(qiáng)了!!哇哇哇!。。

//注意:指針函數(shù)寫法,*函數(shù)名要用括號(hào)括起來啊
/****************************************************************************/

簡(jiǎn)單舉例: void Callback_shao(int a , int (*diaoba) (int a,int b))//指針函數(shù)直接在參數(shù)里聲明
              {
                   int can;
(*diaoba)(can,a);//要用這指針函數(shù)啊,而且參數(shù)要賦值
    (*diaoba)(22,33); //參數(shù)要賦值
                (*diaoba)(a,can);//指針函數(shù)的參數(shù)寫什么,就隨便你了
                  
}
              這個(gè)指針參數(shù),到時(shí)候指向哪個(gè)函數(shù)。函數(shù)里面執(zhí)行的,就是哪個(gè)函數(shù)
        //下面是具體函數(shù)
void  nixie(int fan , int cao) //函數(shù)1,參數(shù)個(gè)數(shù)符合回調(diào)函數(shù)的那個(gè)指針函數(shù)
   {
     里面隨便你啦!!。。。。
}
Void nixiangxie(int  mei  ,int  zhao)//函數(shù)2
{
     里面隨便你啦。。。。
}
void main()  //主函數(shù)
{
     Callback_shao(1,nixie); //回調(diào)時(shí),只寫函數(shù)名就行了。指針嘛,類似指向數(shù)組首地址寫法
     Callback_shao(324,nixiangxie);
}
/****************************************************************************/
也可以用typedef 自定義,下面使用指針函數(shù)就可以直接用函數(shù)名了
typdef int
(*diaoba) (int a,int b);
diaoba  PCallA;//重新定義一個(gè)函數(shù)指針
diaoba  PcallB;
void Callback_shao(int a ,PcallB); //參數(shù)里就可以直接寫函數(shù)名

主函數(shù)里。。。。
void main
{
   Callback_shao(3,nixie);
}

/**************************************************************/


回調(diào)函數(shù)例子:
#include <stdio.h>
void printWelcome(int len)  //函數(shù)實(shí)現(xiàn),回調(diào)函數(shù)會(huì)調(diào)用它,要自己先寫好。
{
       printf("Welcom -- %d\n", len);
}
void printGoodbye(int len) //函數(shù)實(shí)現(xiàn),回調(diào)函數(shù)會(huì)調(diào)用它,要自己先寫好。
{
       printf("Goodbye -- %d\n", len);
}
void callback(int times, void (* print)(int)) //回調(diào)函數(shù),有個(gè)參數(shù)是個(gè)函數(shù)指針
{
       int i;
       print(i);//指針函數(shù)你要用到他,不用它,他回調(diào)個(gè)屁啊!
       print(times);//指針函數(shù)你要用,不用它,他回調(diào)個(gè)屁。。!
}
void main(void)
{
       callback(10, printWelcome); //傳入具體的函數(shù)地址
      callback(10, printGoodbye);//傳入具體的函數(shù)地址
       printWelcome(5);
}
/******************************************************************************************************************/
回調(diào)函數(shù)的寫法,還有幾種,下面的參考

#include<stdio.h>
// 方法指針的格式為:int (*ptr)(char *p) 即:返回值(指針名)(參數(shù)列表)
typedef int (*CallBackFun)(char *p); // 為回調(diào)函數(shù)命名,類型命名為 CallBackFun,參數(shù)為char *p 。

程序舉例:
typedef int (*CallBackFun)(char *p); //這是回調(diào)函數(shù),自定義成了一個(gè)別名CallBackFun
int Afun(char *p)
{
printf("Afun 回調(diào)打印出字符%s!\n", p);
return 0;
}
int Cfun(char *p)
{ // 方法 Bfun,格式符合 CallBackFun 的格式,因此可以看作是一個(gè) CallBackFun
printf("Cfun 回調(diào)打印:%s, Nice to meet you!\n", p);
return 0;
}
/*********************************************************************/
//調(diào)用者要先寫好這個(gè)回調(diào)函數(shù)的實(shí)例。才能調(diào)用 回調(diào)函數(shù);卣{(diào)函數(shù)相當(dāng)于制定規(guī)則的,但具體函數(shù)體,函數(shù)名,函數(shù)實(shí)現(xiàn)不細(xì)化,具體細(xì)則還得調(diào)用者自己實(shí)現(xiàn)(即回調(diào)函數(shù)的實(shí)現(xiàn))。
int call(CallBackFun pCallBack, char *p)  //寫法1,
{    // 執(zhí)行回調(diào)函數(shù),方式一:通過命名方式
printf("call 直接打印出字符%s!\n", p);
pCallBack(p);//指針函數(shù)要寫在里面,不用它,回調(diào)個(gè)屁。。!
return 0;
}
/*********************************************************************/
int call2(char *p, int (*ptr)())
{     // 執(zhí)行回調(diào)函數(shù),方式二:直接通過方法指針
printf("==============\n", p);
(*ptr)(p);  //指針函數(shù)要寫在里面,不用它,回調(diào)個(gè)屁。。!
}
/*********************************************************************/
int call3(char *p, CallBackFun pCallBack)
{      // 執(zhí)行回調(diào)函數(shù),方式一:通過命名方式
printf("--------------\n", p);
pCallBack(p); //指針函數(shù)要寫在里面,不用它,回調(diào)個(gè)屁啊。!
}
/*********************************************************************/
int main()
{   
char *p = "hello";
call(Afun, p);   //調(diào)用Afun回調(diào)函數(shù),傳遞參數(shù)*P給Afun函數(shù)
call(Cfun, p); //調(diào)用Cfun回調(diào)函數(shù),傳遞參數(shù)*P給Afun函數(shù)
call2(p, Afun); //調(diào)用Afun回調(diào)函數(shù),傳遞參數(shù)*P給Afun函數(shù)
    call2(p, Cfun); //調(diào)用Cfun回調(diào)函數(shù),傳遞參數(shù)*P給Afun函數(shù)
call3(p, Afun);  //調(diào)用Afun回調(diào)函數(shù),傳遞參數(shù)*P給Afun函數(shù)
    call3(p, Cfun); //調(diào)用Cfun回調(diào)函數(shù),傳遞參數(shù)*P給Afun函數(shù)
// int i = getchar();
// printf("Input: %c \n", i);
return 0;
}
/*********************************************************************/
Linux下的編譯、輸出:
[jhliu@localhost src]$ gcc -o func_callback func_callback.c
[jhliu@localhost src]$ ./func_callback
call 直接打印出字符hello!
Afun 回調(diào)打印出字符hello!
==============
call 直接打印出字符hello!
Cfun 回調(diào)打印:hello, Nice to meet you!
==============
Afun 回調(diào)打印出字符hello!
==============
Cfun 回調(diào)打印:hello, Nice to meet you!
--------------
Afun 回調(diào)打印出字符hello!
--------------
Cfun 回調(diào)打印:hello, Nice to meet you!
[jhliu@localhost src]$
/*****************下面是少占魚測(cè)試通過的用法舉例(vc6.0)***********************************/
#include "iostream.h"
#define uint8 unsigned int
typedef void (*halCBack_t) (uint8 keys, uint8 state); //指針函數(shù),注意加了自定義typedef后,下面才能重命名

void KeyCallback ( uint8 keys, uint8 state ); //具體實(shí)現(xiàn)函數(shù)
void LEDCallback ( uint8 keys, uint8 state ); //具體實(shí)現(xiàn)函數(shù)
int Ligback( uint8 keys, uint8 state ); //具體實(shí)現(xiàn)函數(shù)
void HalKeyConfig (uint8 st, halCBack_t cback);//注意指針函數(shù)加了typedef后,這里才能當(dāng)關(guān)鍵字聲明
void ShiYong (uint8 ffff, int (*halCBack_t) (uint8 keys, uint8 state));//如果指針函數(shù)沒有typedef,要這樣使用
//注意指針函數(shù)加了自定義typedef后,這里才能定義,否則報(bào)錯(cuò)
halCBack_t pHalKeyProcessFunction=KeyCallback; //聲明指針函數(shù)變量并指向一個(gè)具體函數(shù)地址

halCBack_t taskCall[]=
{
KeyCallback,
LEDCallback  
}; //指針函數(shù)數(shù)組

void main()
{
HalKeyConfig( 1, KeyCallback ); //調(diào)用該函數(shù),參數(shù)里的指針函數(shù)指針指向具體函數(shù)即可
HalKeyConfig( 2, LEDCallback );  
taskCall[0](11,11);
taskCall[1](22,22);
ShiYong(33,Ligback);
(*pHalKeyProcessFunction)(44,44); //指針函數(shù)具體使用
}
void HalKeyConfig (uint8 st, halCBack_t cback)//某個(gè)函數(shù),調(diào)用指針函數(shù)作參數(shù)
{
    cback(st,st);
}
void ShiYong (uint8 fa, int (*halCBack_t) (uint8 keys, uint8 state))
{
  (*halCBack_t) (fa, fa);
  cout<<"使用"<<endl;
}
void KeyCallback ( uint8 keys, uint8 state ) //具體實(shí)現(xiàn)函數(shù)
{
   cout<<"按鍵函數(shù)"<<keys<<state<<endl;
   
}

void LEDCallback ( uint8 keys, uint8 state ) //具體實(shí)現(xiàn)函數(shù)
{
  cout<<"LED函數(shù)"<<keys<<state<<endl;
}

int Ligback( uint8 keys, uint8 state ) //具體實(shí)現(xiàn)函數(shù)
{
  cout<<"Lig函數(shù)"<<keys<<state<<endl;
  return 1;
}

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

ID:62890 發(fā)表于 2015-1-4 08:48 | 顯示全部樓層
學(xué)習(xí)了
回復(fù)

使用道具 舉報(bào)

ID:476556 發(fā)表于 2020-3-18 09:40 | 顯示全部樓層
學(xué)習(xí)了,簡(jiǎn)單粗暴的樓主
回復(fù)

使用道具 舉報(bào)

ID:89515 發(fā)表于 2020-6-1 15:35 來自手機(jī) | 顯示全部樓層
學(xué)習(xí)了,干貨很好。。!
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表