在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

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

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

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

【RT-Thread學(xué)習(xí)筆記】一種C語(yǔ)言宏定義的寫(xiě)法

嵌入式物聯(lián)網(wǎng)開(kāi)發(fā) ? 來(lái)源:嵌入式物聯(lián)網(wǎng)開(kāi)發(fā) ? 作者:嵌入式物聯(lián)網(wǎng)開(kāi)發(fā) ? 2022-07-30 13:41 ? 次閱讀

文章目錄

  • 1 寫(xiě)在前面
  • 2 問(wèn)題需求
  • 3 代碼實(shí)踐
    • 3.1 編寫(xiě)代碼
    • 3.2 結(jié)果驗(yàn)證
  • 4 經(jīng)驗(yàn)總結(jié)
  • 5 參考鏈接
  • 6 更多分享


1 寫(xiě)在前面

宏定義在 C語(yǔ)言中,是一種很常見(jiàn)的語(yǔ)法;經(jīng)常閱讀開(kāi)源代碼,你會(huì)發(fā)現(xiàn),使用好C語(yǔ)言的宏定義,真的可以寫(xiě)出更加整潔,可讀性非常高的高質(zhì)量代碼。

本文將描述一個(gè)需要使用宏定義技巧來(lái)解決的問(wèn)題場(chǎng)景,希望對(duì)大家理解和使用C語(yǔ)言的宏定義有所幫助和提高。

2 問(wèn)題需求

最近恰好在項(xiàng)目開(kāi)發(fā)的過(guò)程中,遇到了一個(gè)有關(guān)宏定義的問(wèn)題。項(xiàng)目運(yùn)用的背景如下:

項(xiàng)目中有個(gè)頭文件中定義了一個(gè)宏定義,比如是 #define CFG_LOGGER_NAME uart
然后,在某個(gè)C文件中需要將這個(gè)宏定義轉(zhuǎn)換成對(duì)應(yīng)的字符串類型,即為 “uart” ;很明顯,如果按以下的幾種方式定義,肯定得不到期望的結(jié)果:

方式1: #define CFG_LOGGER_NAME_STR  "CFG_LOGGER_NAME"

方式2: #define CFG_LOGGER_NAME_STR  #CFG_LOGGER_NAME

方式3: #define CFG_LOGGER_NAME_STR  ##CFG_LOGGER_NAME

3 代碼實(shí)踐

3.1 編寫(xiě)代碼

為了解決這個(gè)問(wèn)題,特意再次去查看了有關(guān)C語(yǔ)言宏定義的語(yǔ)法,終于找到了解決方法,具體的思路是,需要用一個(gè) “中間宏函數(shù)” 做轉(zhuǎn)換,我們用代碼來(lái)實(shí)踐一下。

#include 

#include  

#define TEST 						uart
#define TO_STR(x) 					#x

#define CFG_LOGGER_NAME				uart 
#define TO_STRING(x)				#x
#define _CFG_LOGGER_NAME_STR(x)		TO_STRING(x)	 			
#define CFG_LOGGER_NAME_STR 		_CFG_LOGGER_NAME_STR(CFG_LOGGER_NAME) 

/* 這三種都達(dá)不到需求 */
#define CFG_LOGGER_NAME_STR1  		"CFG_LOGGER_NAME"

/* 語(yǔ)法錯(cuò)誤:error: stray ‘#’ in program */
//#define CFG_LOGGER_NAME_STR2  	#CFG_LOGGER_NAME

/* 語(yǔ)法錯(cuò)誤: error: '##' cannot appear at either end of a macro expansion */
//#define CFG_LOGGER_NAME_STR3  	##CFG_LOGGER_NAME

int main(void)
{
	printf("\r\n%s\r\n", TO_STR(TEST));

	printf("\r\n%s\r\n", CFG_LOGGER_NAME_STR);
	
	printf("\r\n%s\r\n", CFG_LOGGER_NAME_STR1);
	
	//printf("\r\n%s\r\n", CFG_LOGGER_NAME_STR2);
	
	//printf("\r\n%s\r\n", CFG_LOGGER_NAME_STR3);

	return 0;
}

3.2 結(jié)果驗(yàn)證

驗(yàn)證環(huán)境如下:

recan@ubuntu:~$ uname -a
Linux ubuntu 5.4.0-65-generic #73-Ubuntu SMP Mon Jan 18 17:25:17 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
recan@ubuntu:~$ 
recan@ubuntu:~$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with:
Thread model: posix
gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1) 

代碼編譯:

gcc -o test test.c

結(jié)果運(yùn)行:

recan@ubuntu:~$ ./test

TEST

uart

CFG_LOGGER_NAME

查看宏定義展開(kāi)后的預(yù)處理文件:

recan@ubuntu:~$ gcc -E -o test.i test.c | tail -n 20 test.i
# 499 "/usr/include/string.h" 3 4

# 4 "test.c" 2
# 22 "test.c"

# 22 "test.c"
int main(void)
{
 printf("\r\n%s\r\n", "TEST");

 printf("\r\n%s\r\n", "uart");

 printf("\r\n%s\r\n", "CFG_LOGGER_NAME");

 return 0;
}

我們可以看到宏代碼的展開(kāi)是符合我們的預(yù)期的,也只有CFG_LOGGER_NAME_STR 這一種寫(xiě)法是滿足我們問(wèn)題需求的。

4 經(jīng)驗(yàn)總結(jié)

  • 宏定義看似很簡(jiǎn)單,沒(méi)實(shí)踐出來(lái)的時(shí)候,有時(shí)候會(huì)想不通為什么會(huì)這么被展開(kāi)?
  • 在gcc編譯器下查看宏定義被展開(kāi)的內(nèi)容使用的是-E選項(xiàng)。
  • C語(yǔ)言宏定義中的 “#” 和 “##” 是有特殊用法的,必須要用于帶參數(shù)的宏定義中,否則會(huì)報(bào)語(yǔ)法錯(cuò)誤。
  • 留個(gè)疑問(wèn):為何加了一個(gè)中間宏函數(shù)轉(zhuǎn)了一道手,就能得到預(yù)期的內(nèi)容?

5 參考鏈接

  • C語(yǔ)言的宏定義
  • 帶參數(shù)和不帶參數(shù)的宏定義

6 更多分享

架構(gòu)師李肯

一個(gè)專注于嵌入式IoT領(lǐng)域的架構(gòu)師。有著近10年的嵌入式一線開(kāi)發(fā)經(jīng)驗(yàn),深耕IoT領(lǐng)域多年,熟知IoT領(lǐng)域的業(yè)務(wù)發(fā)展,深度掌握IoT領(lǐng)域的相關(guān)技術(shù)棧,包括但不限于主流RTOS內(nèi)核的實(shí)現(xiàn)及其移植、硬件驅(qū)動(dòng)移植開(kāi)發(fā)、網(wǎng)絡(luò)通訊協(xié)議開(kāi)發(fā)、編譯構(gòu)建原理及其實(shí)現(xiàn)、底層匯編及編譯原理、編譯優(yōu)化及代碼重構(gòu)、主流IoT云平臺(tái)的對(duì)接、嵌入式IoT系統(tǒng)的架構(gòu)設(shè)計(jì)等等。擁有多項(xiàng)IoT領(lǐng)域的發(fā)明專利,熱衷于技術(shù)分享,有多年撰寫(xiě)技術(shù)博客的經(jīng)驗(yàn)積累,連續(xù)多月獲得RT-Thread官方技術(shù)社區(qū)原創(chuàng)技術(shù)博文優(yōu)秀獎(jiǎng),榮獲CSDN博客專家、CSDN物聯(lián)網(wǎng)領(lǐng)域優(yōu)質(zhì)創(chuàng)作者、2021年度CSDN&RT-Thread技術(shù)社區(qū)之星、RT-Thread官方嵌入式開(kāi)源社區(qū)認(rèn)證專家、RT-Thread 2021年度論壇之星TOP4、華為云云享專家(嵌入式物聯(lián)網(wǎng)架構(gòu)設(shè)計(jì)師)等榮譽(yù)。堅(jiān)信【知識(shí)改變命運(yùn),技術(shù)改變世界】!

歡迎關(guān)注我的github倉(cāng)庫(kù)01workstation,日常分享一些開(kāi)發(fā)筆記和項(xiàng)目實(shí)戰(zhàn),歡迎指正問(wèn)題。

同時(shí)也非常歡迎關(guān)注我的專欄,有問(wèn)題的話,可以跟我討論,知無(wú)不答,謝謝大家。

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

    關(guān)注

    180

    文章

    7628

    瀏覽量

    139694
  • 宏定義
    +關(guān)注

    關(guān)注

    0

    文章

    51

    瀏覽量

    9154
  • RT-Thread
    +關(guān)注

    關(guān)注

    31

    文章

    1348

    瀏覽量

    41368
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    RT-Thread學(xué)習(xí)筆記】使用scons命令生成靜態(tài)庫(kù)

    RT-Thread學(xué)習(xí)筆記】如何使用scons 命令中buildlib的生成靜態(tài)庫(kù)?
    的頭像 發(fā)表于 07-27 09:13 ?6627次閱讀
    【<b class='flag-5'>RT-Thread</b><b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b>】使用scons命令生成靜態(tài)庫(kù)

    RT-ThreadC語(yǔ)言編碼規(guī)范

    這是RT-Thread 開(kāi)發(fā)人員的開(kāi)發(fā)指引。RT-Thread 做為份開(kāi)源軟件,它需要由不同的人采用合作的方式完成,這份文檔是開(kāi)發(fā)人員的
    的頭像 發(fā)表于 02-21 16:50 ?2681次閱讀

    RT-Thread Nano入門(mén)學(xué)習(xí)筆記

    RT-Thread Nano入門(mén)學(xué)習(xí)筆記
    發(fā)表于 11-26 12:36 ?20次下載
    <b class='flag-5'>RT-Thread</b> Nano入門(mén)<b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b>

    RT-Thread 應(yīng)用筆記 - RTC Alarm 組件的使用

    RT-Thread 應(yīng)用筆記 - 不正確使用LOG也會(huì)引發(fā)hard faultRT-Thread 應(yīng)用筆記 - RTC Alarm 組件的使用RT-
    發(fā)表于 01-25 18:18 ?10次下載
    <b class='flag-5'>RT-Thread</b> 應(yīng)用<b class='flag-5'>筆記</b> - RTC Alarm 組件的使用

    RT-Thread 內(nèi)核學(xué)習(xí)筆記 - 理解defunct僵尸線程

    RT-Thread 內(nèi)核學(xué)習(xí)筆記 - 內(nèi)核對(duì)象rt_objectRT-Thread 內(nèi)核學(xué)習(xí)筆記
    發(fā)表于 01-25 18:19 ?9次下載
    <b class='flag-5'>RT-Thread</b> 內(nèi)核<b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b> - 理解defunct僵尸線程

    RT-Thread 內(nèi)核學(xué)習(xí)筆記 - 設(shè)備模型rt_device的理解

    RT-Thread 內(nèi)核學(xué)習(xí)筆記 - 內(nèi)核對(duì)象rt_objectRT-Thread 內(nèi)核學(xué)習(xí)筆記
    發(fā)表于 01-25 18:19 ?8次下載
    <b class='flag-5'>RT-Thread</b> 內(nèi)核<b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b> - 設(shè)備模型<b class='flag-5'>rt</b>_device的理解

    RT-Thread 內(nèi)核學(xué)習(xí)筆記 - 內(nèi)核對(duì)象鏈表結(jié)構(gòu)深入理解

    RT-Thread 內(nèi)核學(xué)習(xí)筆記 - 內(nèi)核對(duì)象rt_objectRT-Thread 內(nèi)核學(xué)習(xí)筆記
    發(fā)表于 01-25 18:23 ?6次下載
    <b class='flag-5'>RT-Thread</b> 內(nèi)核<b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b> - 內(nèi)核對(duì)象鏈表結(jié)構(gòu)深入理解

    RT-Thread 內(nèi)核學(xué)習(xí)筆記 - 內(nèi)核對(duì)象初始化鏈表組織方式

    RT-Thread 內(nèi)核學(xué)習(xí)筆記 - 內(nèi)核對(duì)象rt_objectRT-Thread 內(nèi)核學(xué)習(xí)筆記
    發(fā)表于 01-25 18:24 ?3次下載
    <b class='flag-5'>RT-Thread</b> 內(nèi)核<b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b> - 內(nèi)核對(duì)象初始化鏈表組織方式

    RT-Thread 內(nèi)核學(xué)習(xí)筆記 - 內(nèi)核對(duì)象操作API

    RT-Thread 內(nèi)核學(xué)習(xí)筆記 - 內(nèi)核對(duì)象rt_objectRT-Thread 內(nèi)核學(xué)習(xí)筆記
    發(fā)表于 01-25 18:26 ?7次下載
    <b class='flag-5'>RT-Thread</b> 內(nèi)核<b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b> - 內(nèi)核對(duì)象操作API

    RT-Thread學(xué)習(xí)筆記 --(3)RT-Thread自動(dòng)初始化機(jī)制分析

    相信不少工程師在閱讀RT-Thread相關(guān)源代碼的時(shí)候,都會(huì)經(jīng)常看到如下圖所示的定義,按照定義的命名來(lái)理解,這些
    發(fā)表于 01-25 18:55 ?1次下載
    <b class='flag-5'>RT-Thread</b><b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b> --(3)<b class='flag-5'>RT-Thread</b>自動(dòng)初始化機(jī)制分析

    RT-Thread學(xué)習(xí)筆記 RT-Thread的架構(gòu)概述

    RT-Thread 簡(jiǎn)介 作為名 RTOS 的初學(xué)者,也許你對(duì) RT-Thread 還比較陌生。然而,隨著你的深入接觸,你會(huì)逐漸發(fā)現(xiàn) RT-Thread 的魅力和它相較于其他同類型
    的頭像 發(fā)表于 07-09 11:27 ?4825次閱讀
    <b class='flag-5'>RT-Thread</b><b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b> <b class='flag-5'>RT-Thread</b>的架構(gòu)概述

    RT-Thread學(xué)習(xí)筆記】Makefile的FORCE

    RT-Thread學(xué)習(xí)筆記】十分鐘學(xué)會(huì)Makefile的FORCE
    的頭像 發(fā)表于 07-30 13:55 ?2961次閱讀
    【<b class='flag-5'>RT-Thread</b><b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b>】Makefile的FORCE

    RT-Thread學(xué)習(xí)筆記】如何抓取終端的網(wǎng)絡(luò)報(bào)文

    RT-Thread學(xué)習(xí)筆記】如何抓取終端的網(wǎng)絡(luò)報(bào)文?
    的頭像 發(fā)表于 07-30 13:57 ?3208次閱讀
    【<b class='flag-5'>RT-Thread</b><b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b>】如何抓取終端的網(wǎng)絡(luò)報(bào)文

    RT-Thread學(xué)習(xí)筆記】用memwatch排除內(nèi)存泄露

    RT-Thread學(xué)習(xí)筆記】使用memwatch排除內(nèi)存泄露
    的頭像 發(fā)表于 07-30 14:01 ?2692次閱讀
    【<b class='flag-5'>RT-Thread</b><b class='flag-5'>學(xué)習(xí)</b><b class='flag-5'>筆記</b>】用memwatch排除內(nèi)存泄露

    基于RT-Thread Studio學(xué)習(xí)

    前期準(zhǔn)備:從官網(wǎng)下載 RT-Thread Studio,弄個(gè)賬號(hào)登陸,開(kāi)啟rt-thread學(xué)習(xí)之旅。
    的頭像 發(fā)表于 05-15 11:00 ?4787次閱讀
    基于<b class='flag-5'>RT-Thread</b> Studio<b class='flag-5'>學(xué)習(xí)</b>
    主站蜘蛛池模板: 人操人操| 奇米激情 | 操女网站| 在线观看日本免费视频大片一区 | 午夜视频在线观看免费高清 | 国产jzjzjz免费大全视频 | 一级毛片真人免费观看 | 99热这里只有精品一区二区三区 | 欧美白人极品性喷潮 | 免费啪视频观在线视频在线 | 狠狠色综合久久久久尤物 | 激情福利网 | 狠狠色噜狠狠狠狠色综合久 | 国产精品成人免费观看 | 日本a级片视频 | 国模在线 | 亚洲乱码卡一卡二卡三 | 黄a在线 | 精品伊人久久大线蕉地址 | 夜色sese| 欧美污视频网站 | 夜夜橹橹网站夜夜橹橹 | 天天色天天综合网 | 天天做天天爱天天大综合 | 日韩大尺度视频 | 好吊色37pao在线观看 | 看全色黄大色大片免费 | 婷婷亚洲综合一区二区 | 黄色大片免费观看 | 国产成人精品本亚洲 | 午夜刺激爽爽视频免费观看 | 天堂成人一区二区三区 | 伊人久久大香线蕉电影院 | 免费黄色大片网站 | 午夜剧场操一操 | 日本大片成人免费播放 | 亚洲免费视频播放 | 4hc44四虎www视频 | 国产乱码精品一区二区 | 伊人888| 一级片在线观看免费 |