<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 設計應用 > C語(yǔ)言回調函數學(xué)習

C語(yǔ)言回調函數學(xué)習

作者: 時(shí)間:2011-05-29 來(lái)源:網(wǎng)絡(luò ) 收藏

對指針的應用是C編程的精髓所在,而回調就是C里面對指針的高級應用。簡(jiǎn)而言之,回調是一個(gè)通過(guò)函數指針調用的函數。如果你把函數指針(函數的入口地址)傳遞給另一個(gè)函數,當這個(gè)函數指針被用來(lái)調用它所指向的函數時(shí),我們就說(shuō)這個(gè)函數是回調函數。

本文引用地址:http://dyxdggzs.com/article/150685.htm

  為什么要使用回調函數呢?我們先看一個(gè)小例子:

  Node * Search_List (Node * node, const int value)

  {

  while (node != NULL)

  {

  if (node -> value == value)

  {

  break;

  }

  node = node -> next;

  }

  return node;

  }

  這個(gè)函數用于在一個(gè)單向鏈表中查找一個(gè)指定的值,返回保存這個(gè)值的節點(diǎn)。它的參數是指向這個(gè)鏈表第一個(gè)節點(diǎn)的指針以及要查找的值。這個(gè)函數看上去很簡(jiǎn)單,但是我們考慮一個(gè)問(wèn)題:它只能適用于值為整數的鏈表,如果查找一個(gè)字符串鏈表,我們不得不再寫(xiě)一個(gè)函數,其實(shí)大部分代碼和現在這個(gè)函數相同,只是第二個(gè)參數的類(lèi)型和比較的方法不同。

  其實(shí)我們更希望令查找函數與類(lèi)型無(wú)關(guān),這樣它就能用于查找存放任何類(lèi)型值的鏈表了,因此必須改變比較的方式,而借助回調函數就可以達到這個(gè)目的。我們編寫(xiě)一個(gè)函數(回調函數),用于比較兩個(gè)同類(lèi)型的值,然后把一個(gè)指向這個(gè)函數的指針作為參數傳遞給查找函數,查找函數調用這個(gè)比較函數來(lái)執行比較,采用這個(gè)方法,任何類(lèi)型的值得都可以進(jìn)行比較。

  我們還必須給查找函數傳遞一個(gè)指向待比較的值的指針而不是值本身,也就是一個(gè)void *類(lèi)型的形參,這個(gè)指針會(huì )傳遞給回調函數,進(jìn)行最終的比較。這樣的修改可以讓我們傳遞指向任何類(lèi)型的指針到查找函數,從而完成對任何類(lèi)型的比較,這就是指針的好處,我們無(wú)法將字符串、數組或者結構體作為參數傳遞給函數,但是指向它們的指針卻可以。

  現在,我們的查找函數就可以這樣實(shí)現:

  NODE *Search_List(NODE *node, int (*compare)(void const *, void const *) ,

  void const *desired_value);

  {

  while (node != NULL)

  {

  if (compare((node->value_address), desired_value) == 0)

  {

  break;

  }

  node = node->next;

  }

  return node;

  }

  可以看到,用戶(hù)將一個(gè)函數指針傳遞給查找函數,后者將回調這個(gè)函數。

  注意這里我們的鏈表節點(diǎn)是這樣定義的:

  typedef struct list

  {

  void *value_address;

  struct list *next;

  }NODE;

  這樣定義可以讓NODE *類(lèi)型的指針指向存儲任何類(lèi)型數據的鏈表節點(diǎn)。而value_address就是指向具體數據的指針,我們把它定義為void *,表示一個(gè)指向未知類(lèi)型的指針,這樣鏈表就可以存儲任何類(lèi)型的數據了,而我們傳遞給查找函數Search_List的第一個(gè)參數就可以統一表示為:NODE *,否則,還是要分別寫(xiě)查找函數以適應存儲不同數據類(lèi)型的鏈表。

  現在,查找函數與類(lèi)型無(wú)關(guān),因為它不進(jìn)行實(shí)際的比較,因此,我們必須編寫(xiě)針對不同類(lèi)型的比較函數,這是很容易實(shí)現的,因為調用者知道鏈表中所包含的值的類(lèi)型,如果創(chuàng )建幾個(gè)分別包含不同類(lèi)型值的鏈表,為每種類(lèi)型編寫(xiě)一個(gè)比較函數就允許單個(gè)查找函數作用于所有類(lèi)型的鏈表。

  下面是一個(gè)比較函數,用于在一個(gè)整型鏈表中查找:

  注意強制類(lèi)型轉換,比較函數的參數必須被聲明為void *以匹配查找函數的原型,然后強制轉換為(int *)類(lèi)型用于比較整型。

  int int_compare(void const *a, void const *b)

  {

  if (*(int *)a == *(int *)b)

  {

  return 0;

  }

  else

  {

  return -1;

  }

  }

  這個(gè)函數可以這樣被使用:

  desired_node = Search_List(root, int_compare, desired_int_value);

  如果你希望在一個(gè)字符串鏈表中進(jìn)行查找,下面的代碼就可以完成任務(wù):

  desired_node = Search_List(root, strcmp, “abcdefg”);

  正好庫函數strcmp所執行的比較和我們需要的一樣,不過(guò)gcc會(huì )發(fā)出警告信息:因為strcmp的參數被聲明為const char *而不是void const *。

  上面的例子展示了回調函數的基本原理和用法,回調函數的應用是非常廣泛的。通常,當我們想通過(guò)一個(gè)統一接口實(shí)現不同內容的時(shí)候,用回調函數來(lái)實(shí)現就非常合適。任何時(shí)候,如果你所編寫(xiě)的函數必須能夠在不同的時(shí)刻執行不同的類(lèi)型的工作或者執行只能由函數調用者定義的工作,你都可以用回調函數來(lái)實(shí)現。許多窗口系統就是使用回調函數連接多個(gè)動(dòng)作,如拖拽鼠標和點(diǎn)擊按鈕來(lái)指定調用用戶(hù)程序中的某個(gè)特定函數。

c語(yǔ)言相關(guān)文章:c語(yǔ)言教程


c++相關(guān)文章:c++教程




關(guān)鍵詞: 學(xué)習 函數 語(yǔ)言

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>