国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

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

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

3天內不再提示

宏的使用:用宏##粘貼函數,然后用函數指針查找執行的操作

strongerHuang ? 來源:strongerHuang ? 作者:良知猶存 ? 2020-11-20 15:49 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

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

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

一、#define的常規操作

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

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

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

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

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

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

假設稍后調用該宏:

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

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

因此, 展開后的代碼是:

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

二、#define配合##使用

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

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

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

def_u32_array(sample_buffer, 64)

宏展開的效果是:

uint32_tarray_sample_buffer[64];

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

下面就是在Linux內核里面的源代碼:

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

#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)); })

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

#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); })

最后面進行執行__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++中我們也可以將做成一個指針列表,對應好每個函數的名稱后,再次調用該定義的宏參數,就實現了指針調用。

#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內核中的代碼,用來print不同狀態的打印信息,如果大家想要快速掌握這些使用方法,建議大家***Linux內核源碼呢。

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

責任編輯:xj

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

文章出處:【微信公眾號:strongerHuang】歡迎添加關注!文章轉載請注明出處。

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

    關注

    3

    文章

    4417

    瀏覽量

    67502
  • 指針
    +關注

    關注

    1

    文章

    484

    瀏覽量

    71844
  • define
    +關注

    關注

    0

    文章

    16

    瀏覽量

    4127

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

文章出處:【微信號:strongerHuang,微信公眾號:strongerHuang】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    傳遞一個無符號的 long 型指針函數

    C語言允許傳遞指針函數,只需要簡單地聲明函數參數為指針類型即可。 下面的實例中,我們傳遞一個無符號的 long 型指針
    發表于 01-27 11:51

    指針函數詳解

    void (*FunType)(int); /*這樣只是定義一個函數指針類型 */ FunType FunP; /*然后用FunType類型來聲明全局FunP變量*/ int main() { FunP
    發表于 01-23 06:02

    函數指針介紹

    這種函數應該都很熟悉,其實就是一個函數,然后返回值是一個 int 類型,是一個數值 int *fun(int x,int y); 這和上面那個函數唯一的區別就是在
    發表于 01-21 08:11

    函數指針與回調函數解讀

    應用程序將函數注冊為回調。然后,此回調函數由硬件驅動程序作為執行的一部分進行調用。如果不使用回調,就會被編碼為直接調用。這將使硬件驅動程序特定于特定的高級軟件級別,并降低其可重用性?;?/div>
    發表于 01-19 07:34

    C語言函數指針的六個高級的應用場景

    調用的函數。通常,回調函數是在某個庫函數或框架函數中注冊的,當某個條件滿足時,庫函數或框架函數
    發表于 01-04 12:25

    C語言中實現函數的三種方式

    1. 函數介紹 函數,即包含多條語句的定義,其通常為某一被頻繁調用的功能的語句封裝,且不想通過函數
    發表于 12-29 07:34

    函數指針指針函數的區別

    在學習arm過程中發現這“指針函數”與“函數指針”容易搞錯,所以今天,我自己想一次把它搞清楚,找了一些資料,和大家的一些總結,整理到此。和大家分享。   首先它們之間的定義:   1、
    發表于 12-12 06:34

    函數指針的概念

    函數指針是指向函數指針變量。 通常我們說的指針變量是指向一個整型、字符型或數組等變量,而函數
    發表于 12-11 08:10

    如何用函數指針調用函數

    ),因此在獲取函數指針時,可以直接函數名,也可以取函數的地址。 p = Max可以改成 p =Max c = (*p)(a, b)
    發表于 12-11 06:26

    C語言拼接運算符典型使用

    在C語言中,##運算符(稱為[size=16.002px]標記拼接運算符)用于定義中將兩個標記(token)拼接成一個新的標記。它在預處理階段處理,常用于動態生成變量名、函數名或類型名,以提高代碼
    發表于 11-20 08:27

    單片機啟動&庫函數的構成

    會正常跳轉到main函數開始執行,就像啟動文件里面寫的那樣。 至此,啟動文件主要部分及系統默認的上電時鐘已講解完。 如果你看不懂C語言,那就去補習C語言。 如果你看不懂為什么這是在操作寄存器,下一
    發表于 11-18 08:15

    計算程序執行指令數的函數實現

    (來源:手把手教你設計cpu_RISC-V處理器),他們分別存儲了指令計數器的高低32位 至此就大致能理解指令數計算函數的實現原理,即通過csrr指令讀minstreth和minstret寄存器得到執行操作前后的指令計數值,再
    發表于 10-28 06:27

    詳解hal_entry入口函數

    hal_entry函數開始執行。我們直接打開“srchal_entry.c”文件,在hal_entry函數里面編寫我們的代碼。
    的頭像 發表于 07-25 15:34 ?1983次閱讀

    C語言中的內聯函數

    在C編程中,內聯函數都用于避免函數調用的開銷并編寫可復用的邏輯部分,但它們在工作方式和安全性方面存在顯著差異。
    的頭像 發表于 07-25 15:10 ?1909次閱讀
    C語言中的內聯<b class='flag-5'>函數</b>與<b class='flag-5'>宏</b>

    函數指針的六個常見應用場景

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