小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

C|函數(shù)指針與回調(diào)函數(shù)模擬實(shí)現(xiàn)委托與反射

 xpxys99 2021-11-27

函數(shù)是C語言的核心概念。主調(diào)函數(shù)(caller)調(diào)用被調(diào)函數(shù)(callee)是一般的調(diào)用關(guān)系,如果被調(diào)函數(shù)(callee)參數(shù)包含函數(shù)指針,函數(shù)指針還可以形成多一層的調(diào)用關(guān)系,形成第三方函數(shù)的調(diào)用,專業(yè)術(shù)語稱為回調(diào)(callback),通過函數(shù)指針參數(shù)調(diào)用的第三方函數(shù)稱為回調(diào)函數(shù)?;卣{(diào)可以讓被調(diào)函數(shù)(這里是指用函數(shù)指針做函數(shù)參數(shù)的函數(shù))的代碼更加泛化或抽象,能夠簡(jiǎn)單模擬其它編程語言的委托與反射語法。

1 簡(jiǎn)單模擬委托

//C語言簡(jiǎn)單模擬委托//需要用的指針函數(shù)。通過用指針函數(shù)作為地址接收函數(shù)地址,以達(dá)到委托其他函數(shù)實(shí)現(xiàn)某方法的目的。#include <stdio.h>typedef void(* fun)(); //typedef 把void(*)()類型重命名為funvoid func(fun); // 被調(diào)函數(shù)void func_1(); // 回調(diào)函數(shù)1void func_2(); // 回調(diào)函數(shù)2int main() // 主函數(shù)用做主調(diào)函數(shù){ func(func_1); fun f = func_2; f(); func(func_1); func(func_2); getchar(); return 0;}void func(fun f) //fun f為地址,fun * f為f指向的地址的量或者其他{ printf('func\n'); if (f != NULL) { f(); }}void func_1(){ printf('func_1\n');}void func_2(){ printf('func_2\n');}/*funcfunc_1func_2funcfunc_1funcfunc_2*/

2 簡(jiǎn)單模擬反射

//C語言簡(jiǎn)單模擬反射//高級(jí)語言的反射機(jī)制,簡(jiǎn)單來說就是可以通過字符串型獲取對(duì)應(yīng)的類或者函數(shù)。#if 0#include <stdio.h>#include <string.h>typedef void (*callback)(void);typedef struct {    const char *name;    callback fn;}callback_t;void f0();void f1();callback_t callbacks[] = {    {'cmd0', f0},    {'cmd1', f1},};void f0()   // 回調(diào)函數(shù)0{    printf('cmd0');}void f1()  // 回調(diào)函數(shù)1{    printf('cmd1');}void do_callback(const char *name)  {    size_t i;    for (i = 0; i < sizeof(callbacks) / sizeof(callbacks[0]); i++) {        if (!strcmp(callbacks[i].name, name)) {            callbacks[i].fn();        }    }}int main(){    do_callback('cmd1');    getchar();    return 0;}#else/*上例的不便之處在于,當(dāng)需要映射的函數(shù)因分散在不同文件時(shí),每增加一個(gè)新的映射都需要修改這個(gè)數(shù)組,以及頭文件。2 利用自定義段gcc支持通過使用__attribute__((section())),將函數(shù)、變量放到指定的數(shù)據(jù)段中。也就是說,可以讓編譯器幫我們完成上例中向數(shù)組添加成員的動(dòng)作。借助此機(jī)制,回調(diào)函數(shù)可以在任意文件聲明,不需要修改其他文件。自定義段的起始和結(jié)束地址,可以通過變量__start_SECTIONNAME和__stop_SECTIONNAME得到例如通過__attribute__((section('ss'))定義自定義段,其開始地址為&__start_ss,結(jié)束地址為&__stop_ss*/// https://www./runcode/c920/#include <stdio.h>#define SEC __attribute__((__section__('ss'), aligned(sizeof(void*))))void func_1 (int a, int b){    printf('%s %d %d\n', __func__, __LINE__, a+b); }void func_2 (int a, int b){    printf('%s %d %d\n', __func__, __LINE__, a*b); }// 編譯器會(huì)自動(dòng)提供__start_ss,__stop_ss標(biāo)志段ss的起止地址extern size_t __start_ss;extern size_t __stop_ss;typedef struct {    void (*p)(int, int);} node_t;// 結(jié)構(gòu)體變量a位于自定義段ssSEC node_t a = {     .p = func_1, };SEC node_t b = {     .p = func_2, };int main(int argc, char **argv){   int a = 3, b = 4;    node_t *p;    // 遍歷段ss,執(zhí)行node_t結(jié)構(gòu)中的p指向的函數(shù)    for (p = (node_t *)&__start_ss; p < (node_t *)&__stop_ss;p++) {        p->p(a, b);        a+=1;b+=2;    }}/*func_1 6 7func_2 10 24*/#endif

-End-

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多