一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

C|函數(shù)指針與回調(diào)函數(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ù))的代碼更加泛化或抽象,能夠簡單模擬其它編程語言的委托與反射語法。

1 簡單模擬委托

//C語言簡單模擬委托//需要用的指針函數(shù)。通過用指針函數(shù)作為地址接收函數(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 簡單模擬反射

//C語言簡單模擬反射//高級語言的反射機制,簡單來說就是可以通過字符串型獲取對應的類或者函數(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/*上例的不便之處在于,當需要映射的函數(shù)因分散在不同文件時,每增加一個新的映射都需要修改這個數(shù)組,以及頭文件。2 利用自定義段gcc支持通過使用__attribute__((section())),將函數(shù)、變量放到指定的數(shù)據(jù)段中。也就是說,可以讓編譯器幫我們完成上例中向數(shù)組添加成員的動作。借助此機制,回調(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); }// 編譯器會自動提供__start_ss,__stop_ss標志段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-

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    熟妇久久人妻中文字幕| 日韩一区中文免费视频| 日韩欧美综合中文字幕| 不卡免费成人日韩精品| 又色又爽又黄的三级视频| 日韩欧美一区二区久久婷婷| 欧美乱视频一区二区三区 | 日本加勒比在线观看不卡| 亚洲五月婷婷中文字幕| 五月婷婷综合激情啪啪| 国产精品第一香蕉视频| 99久久精品免费看国产高清| 东北女人的逼操的舒服吗| 亚洲精品黄色片中文字幕| 亚洲一区精品二人人爽久久| 亚洲日本加勒比在线播放 | 午夜福利92在线观看| 亚洲中文字幕在线乱码av| 99热九九在线中文字幕| 性感少妇无套内射在线视频| 日韩午夜老司机免费视频| 日本最新不卡免费一区二区| 色婷婷国产熟妇人妻露脸| 亚洲欧洲一区二区综合精品| 国产精品一区二区丝袜| 亚洲妇女黄色三级视频| 人妻亚洲一区二区三区| 日本少妇中文字幕不卡视频| 亚洲中文字幕在线视频频道| 午夜福利视频日本一区| 日韩精品区欧美在线一区| 欧美丰满大屁股一区二区三区| 国产成人精品国产成人亚洲 | 亚洲av日韩av高潮无打码| 国产日韩综合一区在线观看| 亚洲综合日韩精品欧美综合区| 一区二区三区四区亚洲专区| 欧美激情一区二区亚洲专区| 麻豆最新出品国产精品| 色婷婷在线精品国自产拍 | 厕所偷拍一区二区三区视频|