一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

宏的使用:用宏##粘貼函數(shù),然后用函數(shù)指針查找執(zhí)行的操作

strongerHuang ? 來源:strongerHuang ? 作者:良知猶存 ? 2020-11-20 15:49 ? 次閱讀

宏的使用,大家經(jīng)常會用,但是一般只是簡單定義一個符號常量,類似于#define WHEEL_SCALE_MM 0.53f、#define LOG_I(tag, text_fmt, ...) log_i(tag, text_fmt, ##__VA_ARGS__) ,但是除此之外還有宏還有個##粘貼作用,可以配合#define這個常量表達式,可以做成一個宏定義指針函數(shù)列表,繼而查詢執(zhí)行函數(shù)。

話不多說,我們開始今天的分享,首先還是會進行一下常規(guī)的描述,再分享"##"粘貼的妙用。

一、#define的常規(guī)操作

#define預處理器指令和其他預處理器指令一樣, 以#號作為一行的開
始。ANSI和后來的標準都允許#號前面有空格或制表符, 而且還允許在#和
指令的其余部分之間有空格。但是舊版本的C要求指令從一行最左邊開始,
而且#和指令其余部分之間不能有空格。指令可以出現(xiàn)在源文件的任何地
方, 其定義從指令出現(xiàn)的地方到該文件末尾有效。我們大量使用#define指令來定義明示常量(manifest constant) (也叫做符號常量) 。 預處理器指令從#開始運行, 到后面的第1個換行符為止。也就是說, 指
令的長度僅限于一行。然而,在預處理開始前, 編譯器會把多行物理行處理為一行邏輯行。

一般我們會用#define 來進行明示常量,或者做一個簡單的宏替換函數(shù)

#define RX_BUF_SIZE 30#define MBEDTLS_DES_C /*數(shù)據(jù)加密*/#define ExitIsr Encoder_Isr void Encoder_Isr(void){ g.dir_count += (g.dir == 1)? 1 : -1; }每行#define(邏輯行) 都由3部分組成。第1部分是#define指令本身。第
2部分是選定的縮寫, 也稱為宏。有些宏代表值(如本例) , 這些宏被稱為
類對象宏。C 語言還有類函數(shù)宏, 稍后討論。宏的名稱中不允許有空格, 而且必須遵循C變量的命名規(guī)則:只能使用字符、 數(shù)字和下劃線(_) 字符, 而且首字符不能是數(shù)字。第3部分(指令行的其余部分) 稱為替換列表或替換體。
一旦預處理器在程序中找到宏的實例后, 就會用替換體代替該宏。從宏變成最終替換文本的過程稱為宏展開。注意, 可以在#define行使用標準C注釋。如前所述, 每條注釋都會被一個空格代替。

此外我們還會比較多的使用變宏參

通過把宏參數(shù)列表中最后的參數(shù)寫成省略號(即, 3個點...) 來實現(xiàn)這
一功能。這樣, 預定義宏_ _VA_ARGS_ _可用在替換部分中, 表明省略號代表什么。

#define PR(...) printf(_ _VA_ARGS_ _)

假設(shè)稍后調(diào)用該宏:

PR("Howdy");PR("weight = %d, shipping = $%.2f ", wt, sp);

對于第1次調(diào)用, _ _VA_ARGS_ _展開為1個參數(shù):"Howdy"。
對于第2次調(diào)用, _ _VA_ARGS_ _展開為3個參數(shù):"weight = %d,
shipping = $%.2f "、 wt、 sp。

因此, 展開后的代碼是:

printf("Howdy");printf("weight = %d, shipping = $%.2f ", wt, sp);

二、#define配合##使用

很多人應該都知道"##"的用法,它被稱為預處理的粘合劑,與#運算符類似,##運算符可用于類函數(shù)宏的替換部分。而且,##還可以用于對象宏的替換部分。##運算符可以把兩個記號組合成一個記號。

#definedef_u32_array(__name,__size)uint32_tarray_##__name[__size];

實際中,我們可以這樣使用:

def_u32_array(sample_buffer, 64)

宏展開的效果是:

uint32_tarray_sample_buffer[64];

同樣類比于初始化一個數(shù)組,我們也可以粘貼形成一個函數(shù)

下面就是在Linux內(nèi)核里面的源代碼:

其中這個__pcpu_size_call_return宏,通過##粘貼選擇要使用的raw_cpu_read_x 函數(shù)。

#define __pcpu_size_call_return(stem, variable) ({ typeof(variable) pscr_ret__; __verify_pcpu_ptr(&(variable)); switch(sizeof(variable)) { case 1: pscr_ret__ = stem##1(variable); break; case 2: pscr_ret__ = stem##2(variable); break; case 4: pscr_ret__ = stem##4(variable); break; case 8: pscr_ret__ = stem##8(variable); break; default: __bad_size_call_parameter(); break; } pscr_ret__; }) #define raw_cpu_read_1(pcp) raw_cpu_generic_read(pcp)#define raw_cpu_generic_read(pcp) ({ *raw_cpu_ptr(&(pcp)); })

這部分是更高層次的宏定義,將##粘貼的函數(shù)再次定義為一個宏函數(shù)

#define raw_cpu_read(pcp) __pcpu_size_call_return(raw_cpu_read_, pcp) #define __this_cpu_read(pcp) ({ __this_cpu_preempt_check("read"); raw_cpu_read(pcp); })

最后面進行執(zhí)行__this_cpu_read(current_kprobe);

int __kprobes arc_kprobe_handler(unsigned long addr, struct pt_regs *regs){ struct kprobe *p p = __this_cpu_read(current_kprobe);p=get_kprobe((unsignedlong*)addr);... 省略多行代碼 if (p->break_handler && p->break_handler(p, regs)) { setup_singlestep(p, regs); kcb->kprobe_status = KPROBE_HIT_SS; return 1;}

C++中我們也可以將做成一個指針列表,對應好每個函數(shù)的名稱后,再次調(diào)用該定義的宏參數(shù),就實現(xiàn)了指針調(diào)用。

#define AddFunc(Func) FuncPtrTemplate Func##Map(int mode_name, int state_name) { static auto modeMap = Func##Register(); auto pair = std::make_pair(mode_name, state_name); auto mapEntry = modeMap->find(pair); if (mapEntry == modeMap->end()) return nullptr; return mapEntry->second; } bool Mode::Func(State *state) { auto state_id = getStateId(); auto p_function = Func##Map(getId(), state_id); if (p_function) return p_function(this, state); return false; }AddFunc(IsExit); intmain(){ IsExit(p.get());}

這也是Linux內(nèi)核中的代碼,用來print不同狀態(tài)的打印信息,如果大家想要快速掌握這些使用方法,建議大家擼一擼Linux內(nèi)核源碼呢。

這就是我分享的#define的操作方法,里面代碼是實踐過的,如果大家有什么更好的思路,歡迎分享交流哈。

責任編輯:xj

原文標題:用宏##粘貼函數(shù),然后用函數(shù)指針查找執(zhí)行的操作

文章出處:【微信公眾號:strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4365

    瀏覽量

    63905
  • 指針
    +關(guān)注

    關(guān)注

    1

    文章

    484

    瀏覽量

    70920
  • define
    +關(guān)注

    關(guān)注

    0

    文章

    16

    瀏覽量

    3870

原文標題:用宏##粘貼函數(shù),然后用函數(shù)指針查找執(zhí)行的操作

文章出處:【微信號:strongerHuang,微信公眾號:strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦
    熱點推薦

    函數(shù)指針的六個常見應用場景

    應用場景,并結(jié)合示例代碼進行講解。01、回調(diào)函數(shù):解耦代碼,提高靈活性回調(diào)函數(shù)是嵌入式開發(fā)中最常見的函數(shù)指針應用場景之一。它允許我們在函數(shù)
    的頭像 發(fā)表于 04-07 11:58 ?243次閱讀
    <b class='flag-5'>函數(shù)</b><b class='flag-5'>指針</b>的六個常見應用場景

    西門子TIA Portal中函數(shù)FC和函數(shù)塊FB的相互轉(zhuǎn)換

    DC/DC/DC。 設(shè)置 IP 地址:192.168.0.1。 設(shè)置子網(wǎng)掩碼:255.255.255.0。 第2步: 添加一個函數(shù) FC,命名為:MotorFC-FB,作為待轉(zhuǎn)換的函數(shù) FC,
    的頭像 發(fā)表于 01-15 10:07 ?1407次閱讀
    西門子TIA Portal中<b class='flag-5'>函數(shù)</b>FC和<b class='flag-5'>函數(shù)</b>塊FB的相互轉(zhuǎn)換

    定義后面能不能加分號

    define定義的,最后需不需要加分號?
    的頭像 發(fā)表于 01-06 16:35 ?415次閱讀

    CSU-IDE是否支持函數(shù)指針

    在編寫代碼過程中需要使用函數(shù)指針,編譯的時候報不支持,請問是需要設(shè)置,還是軟件本身就不支持
    發(fā)表于 12-22 23:02

    常用SQL函數(shù)及其用法

    SQL(Structured Query Language)是一種用于管理和操作關(guān)系數(shù)據(jù)庫的編程語言。SQL 提供了豐富的函數(shù)庫,用于數(shù)據(jù)檢索、數(shù)據(jù)更新、數(shù)據(jù)刪除以及數(shù)據(jù)聚合等操作。以下是一些常用
    的頭像 發(fā)表于 11-19 10:18 ?1049次閱讀

    SUMIF函數(shù)對比VLOOKUP的優(yōu)勢

    在Excel中,數(shù)據(jù)管理和分析是日常工作中不可或缺的一部分。SUMIF函數(shù)和VLOOKUP函數(shù)是兩個非常受歡迎的函數(shù),它們可以幫助用戶快速地處理和分析數(shù)據(jù)。盡管它們都可以用于查找和匯總
    的頭像 發(fā)表于 11-11 09:16 ?955次閱讀

    SUMIF函數(shù)與SUMIFS函數(shù)的區(qū)別

    SUMIF函數(shù)和SUMIFS函數(shù)都是Excel中用于條件求和的函數(shù),它們可以幫助用戶根據(jù)特定的條件對數(shù)據(jù)進行求和。盡管它們的基本功能相似,但在使用場景和功能上存在一些差異。以下是對這兩個函數(shù)
    的頭像 發(fā)表于 10-30 09:51 ?6778次閱讀

    SUMIF函數(shù)使用教程

    SUMIF函數(shù)是Excel中非常實用的函數(shù)之一,能夠根據(jù)指定條件對數(shù)據(jù)進行篩選和求和操作。以下是對SUMIF函數(shù)使用方法的詳細教程: 一、基本語法 SUMIF
    的頭像 發(fā)表于 10-30 09:50 ?1460次閱讀

    C語言中最常見的定義寫法

    如果讓你C語言寫個定義,我相信大部分同學順手就能寫出define。
    的頭像 發(fā)表于 10-28 11:12 ?656次閱讀

    RTOS中鉤子函數(shù)的用途及用法

    在很多操作系統(tǒng)中,都存在這樣一類API函數(shù)接口:HOOK函數(shù)(也叫鉤子函數(shù))。
    的頭像 發(fā)表于 10-23 16:25 ?658次閱讀
    RTOS中鉤子<b class='flag-5'>函數(shù)</b>的用途及用法

    開源項目!基于 Arduino DIY 漂亮的機械鍵盤

    計算機。然后使用 Keyboard.releaseAll() 函數(shù)釋放按鍵。我還添加了一個小的延遲,以防止重復命令(消除開關(guān)抖動)。Keyboard.press () 函數(shù)接受字母、數(shù)字(格式為’a
    發(fā)表于 08-19 17:02

    科技擬收購APCB 100%股權(quán)

    科技近期發(fā)布重要公告,宣布其計劃通過全資子公司新加坡勝及PSL,以不超過2.787億元人民幣的現(xiàn)金,全面收購APCB Electronics(Thailand)Co.,Ltd.(簡稱APCB)的100%股權(quán)。此次收購標志著勝
    的頭像 發(fā)表于 08-12 15:06 ?868次閱讀

    面試常考+1:函數(shù)指針指針函數(shù)、數(shù)組指針指針數(shù)組

    在嵌入式開發(fā)領(lǐng)域,函數(shù)指針指針函數(shù)、數(shù)組指針指針數(shù)組是一些非常重要但又容易混淆的概念。理解它
    的頭像 發(fā)表于 08-10 08:11 ?1226次閱讀
    面試常考+1:<b class='flag-5'>函數(shù)</b><b class='flag-5'>指針</b>與<b class='flag-5'>指針</b><b class='flag-5'>函數(shù)</b>、數(shù)組<b class='flag-5'>指針</b>與<b class='flag-5'>指針</b>數(shù)組

    TC387中有__disable_interrupts()關(guān)閉所有中斷和打開所有中斷的函數(shù)嗎?

    TC387 芯片中有__disable_irq()和__enable_irq()關(guān)閉所有中斷和打開所有中斷的函數(shù)嗎,請告知
    發(fā)表于 08-01 08:22

    面試中的高頻問題:指針函數(shù)函數(shù)指針,你能完美應對嗎?

    一直覺得C語言較其他語言最偉大的地方就是C語言中的指針,有些人認為指針很簡單,而有些人認為指針很難,當然這里的對簡單和難并不是等價于對指針的理解程度。為此在這里對C語言中的
    的頭像 發(fā)表于 06-22 08:11 ?2134次閱讀
    面試中的高頻問題:<b class='flag-5'>指針</b><b class='flag-5'>函數(shù)</b>與<b class='flag-5'>函數(shù)</b><b class='flag-5'>指針</b>,你能完美應對嗎?