回撥函式(二)
回撥函式作用:
對於很多初學者來說,往往覺得回撥函式很神祕,很想知道回撥函式的工作原理。本文將要解釋什麼是回撥函式、它們有什麼好處、為什麼要使用它們等等問題,在開始之前,假設你已經熟知了函式指標。
(1)什麼是回撥函式? 簡而言之,回撥函式就是一個通過函式指標呼叫的函式。如果你把函式的指標(地址)作為引數傳遞給另一個函式,當這個指標被用為呼叫它所指向的函式時,我們就說這是回撥函式。 (2)為什麼要使用回撥函式? 因為可以把呼叫者與被呼叫者分開。呼叫者不關心誰是被呼叫者,所有它需知道的,只是存在一個具有某種特定原型、某些限制條件(如返回值為int)的被呼叫函式。 如果想知道回撥函式在實際中有什麼作用,先假設有這樣一種情況,我們要編寫一個庫,它提供了某些排序演算法的實現,如氣泡排序、快速排序、shell排序、shake排序等等,但為使庫更加通用,不想在函式中嵌入排序邏輯,而讓使用者來實現相應的邏輯;或者,想讓庫可用於多種資料型別(int、float、string),此時,該怎麼辦呢?可以使用函式指標,並進行回撥。 回撥可用於通知機制,例如,有時要在程式中設定一個計時器,每到一定時間,程式會得到相應的通知,但通知機制的實現者對我們的程式一無所知。而此時,就需有一個特定原型的函式指標,用這個指標來進行回撥,來通知我們的程式事件已經發生。實際上,SetTimer()API使用了一個回撥函式來通知計時器,而且,萬一沒有提供回撥函式,它還會把一個訊息發往程式的訊息佇列。 另一個使用回撥機制的API函式是EnumWindow(),它列舉螢幕上所有的頂層視窗,為每個視窗呼叫一個程式提供的函式,並傳遞視窗的處理程式。如果被呼叫者返回一個值,就繼續進行迭代,否則,退出。EnumWindow()並不關心被呼叫者在何處,也不關心被呼叫者用它傳遞的處理程式做了什麼,它只關心返回值,因為基於返回值,它將繼續執行或退出。 不管怎麼說,回撥函式是繼續自C語言的,因而,在C++中,應只在與C程式碼建立介面,或與已有的回撥介面打交道時,才使用回撥函式。除了上述情況,在C++中應使用虛擬方法或函式符(functor),而不是回撥函式。回撥函式例子:
#include<stdio.h>
// 方法指標的格式為:int (*ptr)(char *p) 即:返回值(指標名)(引數列表)
typedef int (*CallBackFun)(char *p); // 為回撥函式命名,型別命名為 CallBackFun,引數為char *p
int Afun(char *p) { // 方法 Afun,格式符合 CallBackFun 的格式,因此可以看作是一個 CallBackFun
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) { // 執行回撥函式,方式一:通過命名方式
printf("call 直接打印出字元%s!\n", p);
pCallBack(p);
return 0;
}
// int call2(char *p, int (*ptr)(char *p))
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);
call(Cfun, p);
call2(p, Afun);
call2(p, Cfun);
call3(p, Afun);
call3(p, Cfun);
// 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]$
相關推薦
JavaScript使用回撥函式(二)
AJAX - onreadystatechange 事件 菜鳥教程地址http://www.runoob.com/ajax/ajax-xmlhttprequest-onreadystatechange.html/*不使用回撥函式*/<!DOCTYPE html&g
【FreeRTOS】小白進階之任務如何共用FreeRTOS軟體定時器回撥函式(二)
介紹兩個定時器任務如何通過定時器 handle 共用一個回撥函式。 1、標頭檔案宣告和函式定義 #include "FreeRTOS.h" #include "task.h" #include "t
回撥函式(二)
回撥函式作用: 對於很多初學者來說,往往覺得回撥函式很神祕,很想知道回撥函式的工作原理。本文將要解釋什麼是回撥函式、它們有什麼好處、為什麼要使用它們等等問題,在開始之前,假設你已經熟知了函式指標。 (1)什麼是回撥函式? 簡而言之,回撥函式就是一個通過函式指標呼叫的函式。如果你把函式的指標(地址)作為引
回撥函式(轉)
#include<stdio.h> // 方法指標的格式為:int(*ptr)(char *p) 即:返回值(指標名)(引數列表) typedefint (*CallBackFun)(char *p); // 為回撥函式命名,型別命名為 CallBackFun
WebService、Ajax與回撥函式(一)
本例項演示藉助WebService、Ajax技術和回撥函式,從MSSQL資料庫中獲取所需資料,並用JavaScript語言將資料結果顯示到網頁地圖上。 1、WebService (1)在工具箱的Ajax Extentions下面找到ScriptM
淺談C/C++回撥函式(Callback)& 函式指標
摘要:回撥函式就是一個通過函式指標呼叫的函式。如果你把函式的指標(地址)作為引數傳遞給另一個函式,當這個指標被用來呼叫其所指向的函式時,我們就說這是回撥函式。回撥函式不是由該函式的實現方直接呼叫,而是在特定的事件或條件發生時由另外的一方呼叫的,用於對該事件或條件進行響應。
JS之回撥函式(callback)
1.什麼是回撥函式? -- 簡單點說,一個函式被作為引數傳遞給另一個函式(在這裡我們把另一個函式叫做“otherFunction”),回撥函式在otherFunction中被呼叫。 --可以是匿名函式也可以是命名函式 2.回撥函式的特點 (1)自己定義的函式 (2)你沒有呼叫 (
JavaScript基礎總結深入(資料型別、資料_變數_記憶體、物件、函式、回撥函式、this)
資料型別 1、分類 JavaScript 資料型別分為兩大類,分別為:基本型別,又稱為值型別;物件型別,又稱為引用型別。 基本(值)型別 String:任意字元 Number:任意的數字 boolean: true/false undefined: undefi
深入淺出回撥函式(知乎上看到最好的回答)
回撥方法介紹之中國好室友篇(Java示例)前言在Java社群的各種開源工具中,回撥方法的使用俯拾即是。所以熟悉回撥方法無疑能加速自己對開源輪子的掌握。網上搜了一些文章,奈何對回撥方法的介紹大多隻停留在什麼是回撥方法的程度上。本篇文章嘗試從回撥方法怎麼來的、為什麼要使用回撥方法以及在實際專案中如何使用等方面來介
將類的成員函式作為回撥函式(外一篇:友元函式)
問題的提出 我們已知道類具有封裝和資訊隱藏的特性。只有類的成員函式才能訪問類的私有成員,程式中的其他函式是無法訪問私有成員的。非成員函式可以訪問類中的公有成員,但是如果將資料成員都定義為公有的,這又破壞了隱藏的特性。另外,應該看到在某些情況下,特別是在對某些成員函式多次呼叫時,由於引數傳遞,型別檢查和安全性
ajax的回撥函式(done,fail,always)
直接上程式碼 <!DOCTYPE html> <html> <head> <meta charset="utf-8"><title>ajax</title><script type="te
Java 回撥函式(傳統方法和lambda方法)-一個例子秒懂
背景: 想寫一個工具類 Tool.java ,其中方法 public void readOneLine() 負責一行一行地讀檔案,然後根據不同的業務,對每一行進行不同處理。最後輸出到檔案 out.txt 那麼問題來了,根據不同的業務,進行不同處理 怎麼實現?
ROS 類內如何使用成員函式作為subscribe的回撥函式(this指標)
ros::Subscriber sub = n.subscribe("chatter", 1000, &Listener::callback, &listener); 使用類內函式時,將第四個引數替換成this: ros::Subscriber sub
學JS的心路歷程-函式(二)arguments
引數(argument)與函式引數(parameter) 在討論函式時,很多人都會把這兩個搞混,我自己也不例外。 雖然講錯別人也聽得懂,但是我們還是要搞清楚這兩個的定義到底是什麼! 引數是當我們呼叫函式時傳遞給它的值 引數是我們在函式定義中所列出的變數看完還是有點不懂?沒關係,上圖!
JS中回撥函式(一)
一.前奏 多用在使用 js 寫元件時,尤其是元件的事件很多都需要回調函式的支援 假設 A是回撥函式,B是呼叫者,B引數裡一個是指向A的函式指標,即回撥A,同時另外的引數傳遞給A作為引數 二.JS中函式可作為引數傳遞,甚至在另一個函式內部返回 一旦作為引數
字元驅動裝置原理及其相關函式(二)
參看朱有鵬老師嵌入式視屏,第五部分第三章 1、(1)老介面:register_chrdev (2)新介面:register_chrdev_region/alloc_chrdev_region + cdev register_chrdev_region/alloc_chrdev_regio
JS之函式(二)
函式講解二 1、JS三部曲 語義分析、預編譯、解釋執行 2、預編譯詳解  
Spark Streaming狀態管理函式(二)——updateStateByKey的使用(scala版)
updateStateByKey的使用 關於updateStateByKey 注意事項 示例程式碼 執行 結論 關於updateStateByKey 1.重點:首先會以DStream中的資料進行按key做reduce操作,然
C++學習筆記——建構函式(二)
委託建構函式:使用類的其他建構函式執行初始化過程 Clock(int newH, int newM, int newS): hour(newH), minute(newM), second(newS){ } Clock:Clock(0,0,0){} //無參建構函式呼叫有參建構函式,將預設初始化
day 16 - 1 內建函式(二)
內建函式(二) reversed() 返回一個反向的迭代器 k = [1,2,3,4,5] k.reverse() #反轉 print(k) k = [1,2,3,4,5] k2 = reversed(k) #反向的迭代器 print(k2) for i in k2: pri