1. 程式人生 > >C語言回撥函式熟練—使用方法(構建程式框架方便好用)

C語言回撥函式熟練—使用方法(構建程式框架方便好用)

通俗點不行嗎?啊,不行嗎?老外把國人玩的都不是人了。國人還自己玩自己。非把一個簡單的東西複雜化。叫那麼難理解!!窩裡鬥。。。。。。典型!!!!!!!!

 不說那麼複雜的,誰是狗屎,豬屎。就說怎麼用回撥。
使用步驟:
1.寫一個函式A,A裡面有一個引數是個指標函式 比如: int shao(int a,int (*Pcall)(void *p))

2.有個指標函式引數,那他要指向一個函式,OK,寫一個符合格式的函式B 比如 int CaoDan(int c)
3.使用A函式吧,引數賦值後,指標指向了一個函式地址,不就呼叫了嗎 比如 shao(36,CaoDan);
說明:A通過指標呼叫了B函式,函式執行語句裡面,要用到指標才行啊。不然,光指向了。有個屁用啊!!


 int shao(int a,int (*Pcall)(void *p))
{
int PA;
int PS;
(*Pcall)(a); //指標函式的引數賦值,就看你了。想賦值誰都行。
(*Pcall)(PS);
(*Pcall)(PA);
}
void main()
{
shao(3,AFuc);//指向具體函式AFunc首地址
shao(5,BFuc);
}

完畢,就是這麼用的。
簡單說:函式引數裡有函式指標,指標指向的是函式地址,不是變數地址。這樣,函式你就可以隨便寫,都可以用這個回撥函式當一個引數來呼叫,多方便。程式通用性就更強了!!!哇哇哇!!!!

//注意:指標函式寫法,*函式名要用括號括起來啊
/****************************************************************************/

簡單舉例: void Callback_shao(int a , int (*diaoba) (int a,int b))//指標函式直接在引數裡宣告

{

int can;

(*diaoba)(can,a);//要用這指標函式啊,而且引數要賦值
(*diaoba)(22,33); //引數要賦值

(*diaoba)(a,can);//指標函式的引數寫什麼,就隨便你了

 

}

這個指標引數,到時候指向哪個函式。函式裡面執行的,就是哪個函式
        //下面是具體函式

void  nixie(int fan , int cao) //函式1,引數個數符合回撥函式的那個指標函式
{

裡面隨便你啦!!。。。。

}

Void nixiangxie(int  mei  ,int  zhao)//函式2

{

裡面隨便你啦。。。。

}

void main()  //主函式

{

Callback_shao(1,nixie); //回撥時,只寫函式名就行了。指標嘛,類似指向陣列首地址寫法

Callback_shao(324,nixiangxie);

}

/****************************************************************************/
也可以用typedef 自定義,下面使用指標函式就可以直接用函式名了
typdef int
(*diaoba) (int a,int b);
 diaoba  PCallA;//重新定義一個函式指標
 diaoba  PcallB;
 void Callback_shao(int a ,PcallB); //引數裡就可以直接寫函式名

主函式裡。。。。
void main
{
Callback_shao(3,nixie);
}

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

回撥函式例子:

#include <stdio.h>

void printWelcome(int len)  //函式實現,回撥函式會呼叫它,要自己先寫好。

{

printf(“Welcom — %d\n”, len);

}

 

void printGoodbye(int len) //函式實現,回撥函式會呼叫它,要自己先寫好。
{

       printf(“Goodbye — %d\n”, len);

}

 

void callback(int times, void (* print)(int)) //回撥函式,有個引數是個函式指標

{

       int i;

       print(i);//指標函式你要用到他,不用它,他回調個屁啊!!
 print(times);//指標函式你要用,不用它,他回調個屁啊!!!

}

void main(void)

{

       callback(10, printWelcome); //傳入具體的函式地址
      callback(10, printGoodbye);//傳入具體的函式地址

       printWelcome(5);

}

/******************************************************************************************************************/
回撥函式的寫法,還有幾種,下面的參考

#include<stdio.h>

// 方法指標的格式為:int (*ptr)(char *p) 即:返回值(指標名)(引數列表)
typedef int (*CallBackFun)(char *p); // 為回撥函式命名,型別命名為 CallBackFun,引數為char *p 。

程式舉例:

typedef int (*CallBackFun)(char *p);  //這是回撥函式,自定義成了一個別名CallBackFun

int Afun(char *p)
{
printf(“Afun 回撥打印出字元%s!\n”, p);
return 0;
}

int Cfun(char *p)
{ // 方法 Bfun,格式符合 CallBackFun 的格式,因此可以看作是一個 CallBackFun
printf(“Cfun 回撥列印:%s, Nice to meet you!\n”, p);
return 0;
}

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

//呼叫者要先寫好這個回撥函式的例項。才能呼叫 回撥函式。回撥函式相當於制定規則的,但具體函式體,函式名,函式實現不細化,具體細則還得呼叫者自己實現(即回撥函式的實現)。
int call(CallBackFun pCallBack, char *p)  //寫法1,

{    // 執行回撥函式,方式一:通過命名方式
printf(“call 直接打印出字元%s!\n”, p);
pCallBack(p);//指標函式要寫在裡面,不用它,回調個屁啊!!!
return 0;
}

/*********************************************************************/
int call2(char *p, int (*ptr)())

{     // 執行回撥函式,方式二:直接通過方法指標
printf(“==============\n”, p);
(*ptr)(p);  //指標函式要寫在裡面,不用它,回調個屁啊!!!
}

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

int call3(char *p, CallBackFun pCallBack)

{      // 執行回撥函式,方式一:通過命名方式
printf(“————–\n”, p);
pCallBack(p); //指標函式要寫在裡面,不用它,回調個屁啊!!!
}

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

int main()

{

char *p = “hello”;

call(Afun, p);   //呼叫Afun回撥函式,傳遞引數*P給Afun函式

call(Cfun, p); //呼叫Cfun回撥函式,傳遞引數*P給Afun函式

call2(p, Afun); //呼叫Afun回撥函式,傳遞引數*P給Afun函式
call2(p, Cfun); //呼叫Cfun回撥函式,傳遞引數*P給Afun函式

call3(p, Afun);  //呼叫Afun回撥函式,傳遞引數*P給Afun函式
call3(p, Cfun); //呼叫Cfun回撥函式,傳遞引數*P給Afun函式

// int i = getchar();
// printf(“Input: %c \n”, i);

return 0;
}

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

Linux下的編譯、輸出:

[[email protected] src]$ gcc -o func_callback func_callback.c
[[email protected] src]$ ./func_callback
call 直接打印出字元hello!
Afun 回撥打印出字元hello!

==============
call 直接打印出字元hello!
Cfun 回撥列印:hello, Nice to meet you!
==============
Afun 回撥打印出字元hello!
==============
Cfun 回撥列印:hello, Nice to meet you!
————–
Afun 回撥打印出字元hello!
————–
Cfun 回撥列印:hello, Nice to meet you!
[[email protected] src]$

/*****************下面是少佔魚測試通過的用法舉例(vc6.0)***********************************/
#include “iostream.h”

#define uint8 unsigned int

typedef void (*halCBack_t) (uint8 keys, uint8 state); //指標函式,注意加了自定義typedef後,下面才能重新命名
void KeyCallback ( uint8 keys, uint8 state ); //具體實現函式
void LEDCallback ( uint8 keys, uint8 state ); //具體實現函式
int Ligback( uint8 keys, uint8 state ); //具體實現函式
void HalKeyConfig (uint8 st, halCBack_t cback);//注意指標函式加了typedef後,這裡才能當關鍵字宣告

void ShiYong (uint8 ffff, int (*halCBack_t) (uint8 keys, uint8 state));//如果指標函式沒有typedef,要這樣使用

//注意指標函式加了自定義typedef後,這裡才能定義,否則報錯
halCBack_t pHalKeyProcessFunction=KeyCallback; //宣告指標函式變數並指向一個具體函式地址
halCBack_t taskCall[]=
{
KeyCallback,
LEDCallback
}; //指標函式陣列
void main()
{

HalKeyConfig( 1, KeyCallback ); //呼叫該函式,引數裡的指標函式指標指向具體函式即可
HalKeyConfig( 2, LEDCallback );
taskCall[0](11,11);
taskCall[1](22,22);
ShiYong(33,Ligback);
(*pHalKeyProcessFunction)(44,44); //指標函式具體使用
}

void HalKeyConfig (uint8 st, halCBack_t cback)//某個函式,呼叫指標函式作引數
{
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 ) //具體實現函式
{
cout<<“按鍵函式”<<keys<<state<<endl;

}
void LEDCallback ( uint8 keys, uint8 state ) //具體實現函式
{
cout<<“LED函式”<<keys<<state<<endl;
}

int Ligback( uint8 keys, uint8 state ) //具體實現函式
{
cout<<“Lig函式”<<keys<<state<<endl;
return 1;
}