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

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

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

C語言代碼的常用技巧

TopSemic嵌入式 ? 來源: 最后一個bug ? 2023-12-05 09:25 ? 次閱讀

#和##對于大部分C語言玩得還算比較溜的朋友并不是很陌生,不過能把這兩個知識點(diǎn)游刃有余的應(yīng)用到所在代碼中的每個角落,似乎并沒有幾個人能夠做到,學(xué)的時候朗朗上口,而編碼的時候卻拋之腦后。

但是今天bug菌還是想重新介紹這兩個“兄弟”,希望大家能夠?qū)懗?秀"一點(diǎn)的代碼~

1#和##基礎(chǔ)

對于這兩個語法的功能都比較簡單,且都是在預(yù)處理階段做一些工作 :

#主要是將宏參數(shù)轉(zhuǎn)化為字符串

##主要是將兩個標(biāo)識符拼接成一個標(biāo)識符

沒點(diǎn)代碼似乎并不是那么形象 :

參考demo:

 1#include
 2#include
 3
 4//#的簡單使用
 5#defineSTR(str)#str
 6
 7//##的簡單使用
 8#defineCMB(a,b)a##b
 9
10intmain(intargc,char*argv[]){
11
12intCMB(uart,1)=5;
13intCMB(uart,2)=10;
14
15printf("#的簡單使用:
");
16printf("%s
",STR(3.1415));
17printf("%s
",STR(abcd));
18
19printf("##的簡單使用:
");
20printf("%d
",uart1);
21printf("%d
",uart2);
22
23return0;
24}

輸出結(jié)果:

de3e1544-9301-11ee-939d-92fbcf53809c.png

從結(jié)果上看來似乎#僅僅只是代替了字符串的雙引號,而##卻實(shí)現(xiàn)了標(biāo)識符的拼接,這樣就為編碼標(biāo)識符的處理上能夠帶來更多的可玩性。 那么,下面bug菌跟大家具體展示一下他們的常用技巧:

2#的玩法

1、標(biāo)識符的“字符串變量"

“#”一般結(jié)合打印語句組合成一個宏定義,可以方便的打印相關(guān)信息,下面給個簡單的實(shí)例就明白了。

 1#include
 2#include
 3
 4//#打印調(diào)試
 5#defineDebugLogExpr(Expr)printf("%s:%d
",#Expr,Expr);
 6
 7//私有參數(shù)訪問
 8intsFucntion(void)
 9{
10staticintvar=10;
11returnvar;
12}
13
14intmain(intargc,char*argv[]){
15
16intDebugVar=50;
17
18DebugLogExpr(DebugVar);//直接打印變量名和變量
19DebugLogExpr(100/5);//打印表達(dá)式及結(jié)果
20DebugLogExpr(sFucntion());//打印相關(guān)函數(shù)名及結(jié)果
21
22return1;
23}

輸出結(jié)果:

de4b02fe-9301-11ee-939d-92fbcf53809c.png ?

這樣的話就不需要總是采用雙引號來單獨(dú)書寫,同時你還可以繼續(xù)擴(kuò)展構(gòu)造更加靈活的宏。

2、結(jié)合##進(jìn)行字符串拼接打印


前面介紹了##進(jìn)行標(biāo)識符的拼接,那么實(shí)現(xiàn)拼接標(biāo)識符轉(zhuǎn)化為字符串看來很簡單吧,于是你會編寫了如下代碼:

 1#include
 2#include
 3
 4//#的簡單使用
 5#defineSTR(str)#str
 6
 7//##的簡單使用
 8#defineCMB(a,b)a##b
 9
10intmain(intargc,char*argv[]){
11
12intCMB(uart,1)=5;
13
14printf("%s
",STR(CMB(uart,1)));
15
16return0;
17}
暗自歡喜的編譯著,然而卻得到了如下結(jié)果:

de595b1a-9301-11ee-939d-92fbcf53809c.png

得到的并不是拼接以后你想要的uart1,難道不能這么玩?當(dāng)然不是,不然也不會在這里拿出來說 。 首先要知道原因 : 進(jìn)行宏定義嵌套的情況,#或者##僅在當(dāng)前宏有效,嵌套宏中不會再次展開,既然當(dāng)前宏無法展開,那么我只能再加一級宏定義作為轉(zhuǎn)換宏進(jìn)行展開,看能不能解決該問題:
 1#include
 2#include
 3
 4//#的簡單使用
 5#defineSTR(str)#str
 6
 7//##的簡單使用
 8#defineCMB(a,b)a##b
 9
10#defineSTR_CON(str)STR(str)//轉(zhuǎn)換宏
11
12intmain(intargc,char*argv[]){
13
14intCMB(uart,1)=5;
15
16printf("%s
",STR_CON(CMB(uart,1)));
17
18return0;
19}
此時輸出的結(jié)果符合我們的預(yù)期:

de6decb0-9301-11ee-939d-92fbcf53809c.png

首先進(jìn)行第一層轉(zhuǎn)換宏替換處理掉##拼接符得到str(uart1),然后進(jìn)行字符串轉(zhuǎn)換符的處理為uart1字符串打印輸出,當(dāng)然以后你會遇到一些復(fù)雜的,不過要訣就是宏替換只會處理當(dāng)前的#或者##,否則就需要增加轉(zhuǎn)換宏提前進(jìn)行宏替換展開。 所以采用##拼接出來的標(biāo)識符想要打印輸出的話,使用#進(jìn)行轉(zhuǎn)換是最直接、方便的。

3##的玩法

##拼接符的玩法有點(diǎn)多,甚至有些還比較繞,當(dāng)然如果你游刃有余的話,這對于重構(gòu)代碼是一把“ 利器 ”。

1、在結(jié)構(gòu)體定義中的妙用

下面是bug菌經(jīng)常在項(xiàng)目代碼中用到的##結(jié)構(gòu)體定義法,也是非常多開源代碼中慣用的做法,相比常規(guī)的結(jié)構(gòu)體定義法,確實(shí)省去很多重復(fù)的代碼。 比如下面的參考代碼 :

 1#include
 2#include
 3
 4#defineDF_STRUCT(name)typedefstructtag##namename;
 5structtag##name
 6
 7DF_STRUCT(DevManage)
 8{
 9intindex;//索引
10intAccess;//權(quán)限
11//...
12};
13
14intmain(intargc,char*argv[]){
15
16DevManagestDevManage;
17
18stDevManage.index=1;
19stDevManage.Access=666;
20
21printf("DevIndex:%d
",stDevManage.index);
22printf("DevAccess:%d
",stDevManage.Access);
23
24return1;
25}
2、統(tǒng)一宏替換

拼接標(biāo)識符意味著符號的粒度更高,而這碎片化的符號進(jìn)行有效的管理,就可以使得符號更加具有通用性和靈活性。 其實(shí)這種思想跟我們代碼模塊話是同樣的道理。 來首先我們用一個兩層拼接體驗(yàn)一下:
 1#include
 2#include
 3
 4//假如這是stm32庫中的宏
 5#defineGPIO_Pin_0((int)0x0001)/*!
  編寫的思路bug菌在代碼中跟大家都標(biāo)注了,相信大家一眼就能看懂,似乎并沒有想象中那么難。 而在前面介紹##的基礎(chǔ)知識提過,只要轉(zhuǎn)換宏寫得夠多,你可以一層套一層,最終獲得你想要的標(biāo)識符,達(dá)到修改一個簡單的宏即可替換一整套宏的效果。 所以關(guān)鍵還是你要清晰的把拼接變量找出來,bug菌這里僅展示了一個拼接變量,當(dāng)然多個也是同樣沒有問題的,跟我們函數(shù)傳遞參數(shù)一樣,不過這樣也會增加整個替換的復(fù)雜度,合理利用即可~

審核編輯:湯梓紅

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

    關(guān)注

    180

    文章

    7604

    瀏覽量

    136841
  • 字符串
    +關(guān)注

    關(guān)注

    1

    文章

    579

    瀏覽量

    20518
  • C代碼
    +關(guān)注

    關(guān)注

    1

    文章

    89

    瀏覽量

    14302
  • 結(jié)構(gòu)體
    +關(guān)注

    關(guān)注

    1

    文章

    130

    瀏覽量

    10844

原文標(biāo)題:同事C代碼中的#、##把我秀了~

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

收藏 人收藏

    評論

    相關(guān)推薦

    單片機(jī)常用C語言代碼

    51單片機(jī)常用C語言代碼
    發(fā)表于 12-25 18:51

    常用C語言代碼

    常用c語言代碼
    發(fā)表于 04-25 15:55

    C語言常用的預(yù)處理命令

    1.基礎(chǔ)知識(1)C語言常用的預(yù)處理命令——typedef具體可見C語言基礎(chǔ)語法知識。(2)延時函數(shù)(知識粗略估計延時時間,若要精確延時,需
    發(fā)表于 07-14 07:10

    常用算法程序集 (C語言描述)(第三版)+源代碼修改

    常用算法程序集 (C語言描述)(第三版)+源代碼修改:1.書中所有的算法均用C語言描述,并存放在
    發(fā)表于 02-08 18:22 ?0次下載

    C語言庫函數(shù)

    常用C語言代碼,包括濾波算法,數(shù)字信號處理
    發(fā)表于 03-24 19:30 ?94次下載

    常用的FPGA代碼

    常用的FPGA代碼,VHDL語言編寫。需要請下載
    發(fā)表于 05-26 11:36 ?16次下載

    220個經(jīng)典的C語言代碼

    本文檔中包含了220個C語言程序源代碼,供網(wǎng)友參考。
    發(fā)表于 08-31 17:47 ?92次下載

    C語言書寫的常用規(guī)范

    C語言書寫的常用規(guī)范
    發(fā)表于 10-26 10:43 ?26次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>書寫的<b class='flag-5'>常用</b>規(guī)范

    嵌入式外中斷c語言代碼

    嵌入式外中斷c語言代碼(arm嵌入式開發(fā)實(shí)例)-嵌入式外中斷c語言代碼,有需要的可以參考!
    發(fā)表于 07-30 11:29 ?4次下載
    嵌入式外中斷<b class='flag-5'>c</b><b class='flag-5'>語言</b><b class='flag-5'>代碼</b>

    C語言冒泡排序工程代碼匯總

    C語言冒泡排序工程代碼匯總
    發(fā)表于 08-30 11:06 ?3次下載

    單片機(jī)中常用C語言語句合集

    單片機(jī)中常用C語言語句合集
    發(fā)表于 01-12 09:24 ?45次下載

    C語言應(yīng)用】如何用C代碼生成一維碼?

    C語言應(yīng)用】如何用C代碼生成一維碼?
    的頭像 發(fā)表于 08-25 12:42 ?2444次閱讀
    【<b class='flag-5'>C</b><b class='flag-5'>語言</b>應(yīng)用】如何用<b class='flag-5'>C</b><b class='flag-5'>代碼</b>生成一維碼?

    178個經(jīng)典c語言代碼

    178個經(jīng)典c語言代碼分享
    發(fā)表于 11-17 16:57 ?173次下載

    C語言代碼規(guī)范

    1. 前言 本文是AliOS Things提供的一套C語言代碼規(guī)范,適用的對象為符合C99標(biāo)準(zhǔn)的C語言
    的頭像 發(fā)表于 06-22 10:38 ?990次閱讀

    hex文件如何查看原c語言代碼

    直接將 .hex 文件轉(zhuǎn)換回原始的 C 語言代碼是不可能的,因?yàn)?.hex 文件是二進(jìn)制文件,它包含了單片機(jī)程序編譯后的機(jī)器碼,這些機(jī)器碼與原始的 C
    的頭像 發(fā)表于 09-02 10:37 ?2307次閱讀