老熟女激烈的高潮_日韩一级黄色录像_亚洲1区2区3区视频_精品少妇一区二区三区在线播放_国产欧美日产久久_午夜福利精品导航凹凸

重慶分公司,新征程啟航

為企業提供網站建設、域名注冊、服務器等服務

C函數指針與回調函數-創新互聯

一、函數指針

創新互聯建站-專業網站定制、快速模板網站建設、高性價比海晏網站開發、企業建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式海晏網站制作公司更省心,省錢,快速模板網站建設找我們,業務覆蓋海晏地區。費用合理售后完善,10年實體公司更值得信賴。

    簡單聲明一個函數指針并不意味著它馬上就可以使用,和其它指針一樣,對函數指針執行簡接訪問之前必須把它初始化為指向某一個函數。

int f(int);

int (*pf)(int)=&f;

    第二個聲明創建了函數指針pf,并把它初始化為指向函數f。函數指針的初始化也可以通過一條賦值語句完成。在函數指針的初始化之前具有f的原型是很重要的,否則編譯器就無法檢查f的類型是否與pf所指向的類型一致。

  初始化表達式中的&操作符是可選的,因為函數名被使用時總是由編譯器把它轉換為函數指針。&操作符只是顯示地說明了編譯器將隱式執行的任務。

    在函數指針被聲明并且初始化之后,我們就可以使用三種方式調用函數:

  int ret;


    ret=f(30);

    ret=(*pf)(30);

    ret=pf(30);

第一條語句簡單的使用名字調用函數f,但它的執行過程可能和我們想的不太一樣。函數名f首先被轉換為一個函數指針,該指針指定函數在內存中的位置。然后,函數調用操作符調用該函數,執行開始于這個地址的代碼。

第二條語句對pf執行簡接訪問操作,它把函數指針轉換為一個函數名。這個轉換并不是真正需要的,因為編譯器在執行函數調用操作符之前又會把它轉換回去。不過,這條語句的效果和第一條語句是完全一樣的。

第三條語句和前兩條語句的效果是一樣的。簡接訪問并非必需,因為編譯器需要的是一個函數指針。這個例子顯示了函數指針通常是如何使用的。

    那么什么時候我們應該使用函數指針呢。兩個最常見的用途是把函數指針作為參數傳遞給函數以及用于轉換表。

二、回調函數

   回調函數,顧名思義,就是使用者自己定義一個函數,使用者自己實現這個函數的程序內容,然后把這個函數作為參數傳入別人(或系統)的函數中,由別人(或系統)的函數在運行時來調用的函數。函數是你實現的,但由別人(或系統)的函數在運行時通過參數傳遞的方式調用,這就是所謂的回調函數。簡單來說,就是由別人的函數運行期間來回調你實現的函數。

    在系統編程的角度:當程序跑起來時,一般情況下,應用程序(application program)會時常通過API調用庫里所預先備好的函數。但是有些庫函數(library function)卻要求應用先傳給它一個函數,好在合適的時候調用,以完成目標任務。這個被傳入的、后又被調用的函數就稱為回調函數(callback function)。

    使用函數指針的一個例子就是回調函數。

例如如下函數:

Node* search_ist(Node *node,void const *value,int (*compare)(void const *,void const *))

{

    while(node(!=NULL){

        if(compare(&node->value,value) ==0)

            {

                break;

            }

        node=node->link;

    }

    return node;

}

    這是一個類型無關的鏈表查找,其中參數函數指針所指向的函數用于比較存儲于鏈表中類型的值。

在上邊的函數中我們把一個函數指針作為參數傳遞給其它函數,后者將回調用戶的函數。任何時候,如果我們所編寫的函數必須能夠在不同的時刻執行不同類型的工作或者執行只能由函數調用者的工作,都可以使用這個技巧。許多窗口系統使用回調函數鏈接多個動作,如拖曳鼠標和點擊按鈕來指定用戶程序中某個特定函數。

同樣也可以這樣使用,在一個特定的鏈表中進行查找:

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

{

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

        return 0;

    else

        return 1;

}

    這個函數可以像下面這樣使用:

    desired_node=search_list(root,&desired_value,compare_ints);

    如果想在一個字符串鏈表中進行查找,也可以這樣:

    desired_node=search_list(root,"desired_value",strcmp);

    不過有的編譯器可能會發出警告,因為strcmp的參數被聲明為char*而不是void*;

三、轉換表

如果有如下代碼:

switch(oper){

case ADD:

    result=add(op1,op2);

    break;

case SUB:

    result=sub(op1,op2);

    break;

case MUL:

    result=mul(op1,op2);

    break;

case DIV:

    result=div(op1,op2);

    break;

...

    對于一個具有上百個操作符計算器而言,這條switch語句將會非常之長。

為了使用switch語句,表示操作符的代碼必須是整數。如果它們是從零開始的整數,我們可以使用轉換表來完成相同的任務。轉換表就是一個函數指針數組。

    創建一個轉換表需要兩個步驟。首先,聲明并初始化一個函數指針數組。函數的原型必須出現在這個數組的聲明之前。

double add{double,double};

double sub{double,double};

double mul{double,double};

double div{double,double};

...

double (*oper_func[])(double,double)={

    add,sub,mul,div,...

};

初始化列表中各個函數的正確順序取決于程序中用于表示每個操作符的×××代碼。這個例子中假定ADD是0,SUB是1,MUL是2,DIV是3,以此類推。

    第二個步驟是用下面這條語句替換前面整條switch語句。

    result=oper_func[oper](op1,op2);

oper從數組中選擇正確的函數指針,而函數調用操作符將執行這個函數。

另外有需要云服務器可以了解下創新互聯scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業上云的綜合解決方案,具有“安全穩定、簡單易用、服務可用性高、性價比高”等特點與優勢,專為企業上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。


文章名稱:C函數指針與回調函數-創新互聯
網站路徑:http://www.xueling.net.cn/article/cocioi.html

其他資訊

在線咨詢
服務熱線
服務熱線:028-86922220
TOP
主站蜘蛛池模板: 麻豆www传媒入口 | 男人网站在线 | 亚洲GV天堂GV无码男同 | 日韩一级| 免费高清一区二区三区 | 色综合久久久久综合一小说 | 欧美色欧美亚洲高清在线观看 | A片粗大的内捧猛烈进出AVV | 黄视频在线观看视频 | 美国人性欧美XXXX | 亚洲激情四射视频中文字幕久久 | 亚洲精品综合一二三区在线观看 | 内射少妇36P九色 | 欧美日韩国产一区精品一区 | 日产精品久久久久久久性色91 | 欧美性大战久久久久久久蜜臀 | 无码少妇一区二区三区免费看 | 自拍视频在线观看 | 91艹逼视频| 无码区a毛片免费视频 | 在线中文字幕有码中文 | 精产国品一二三区 | 色哟哟国产成人精品免费 | 日本十八禁视频无遮挡尤物 | 丰满的少妇XXXXX青青青 | 91火爆视频 | 成av人片一区二区三区久久 | 亚洲不卡视频在线观看 | 日韩精品免费一区 | 无遮挡边摸边吃奶边做视频免费 | 午夜aaaa| 扒开双腿疯狂进出爽爽爽动态图 | 顶级黄色片 | 亚洲AV无码一区二区三区国产 | 久久青青操 | 亚洲情综合五月天 | 被黑人粗黑大肉奉视频 | 一夲道无码人妻精品一区二区 | 中文字幕无码中文字幕有码在线 | 99国产免费 | 国内揄拍国内精品少妇国语 |