精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

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

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

3天內不再提示

【RT-Thread學習筆記】一種C語言宏定義的寫法

嵌入式物聯網開發 ? 來源:嵌入式物聯網開發 ? 作者:嵌入式物聯網開發 ? 2022-07-30 13:41 ? 次閱讀

文章目錄

  • 1 寫在前面
  • 2 問題需求
  • 3 代碼實踐
    • 3.1 編寫代碼
    • 3.2 結果驗證
  • 4 經驗總結
  • 5 參考鏈接
  • 6 更多分享


1 寫在前面

宏定義在 C語言中,是一種很常見的語法;經常閱讀開源代碼,你會發現,使用好C語言的宏定義,真的可以寫出更加整潔,可讀性非常高的高質量代碼。

本文將描述一個需要使用宏定義技巧來解決的問題場景,希望對大家理解和使用C語言的宏定義有所幫助和提高。

2 問題需求

最近恰好在項目開發的過程中,遇到了一個有關宏定義的問題。項目運用的背景如下:

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

方式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 代碼實踐

3.1 編寫代碼

為了解決這個問題,特意再次去查看了有關C語言宏定義的語法,終于找到了解決方法,具體的思路是,需要用一個 “中間宏函數” 做轉換,我們用代碼來實踐一下。

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

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

/* 語法錯誤:error: stray ‘#’ in program */
//#define CFG_LOGGER_NAME_STR2  	#CFG_LOGGER_NAME

/* 語法錯誤: 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 結果驗證

驗證環境如下:

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

結果運行:

recan@ubuntu:~$ ./test

TEST

uart

CFG_LOGGER_NAME

查看宏定義展開后的預處理文件:

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

我們可以看到宏代碼的展開是符合我們的預期的,也只有CFG_LOGGER_NAME_STR 這一種寫法是滿足我們問題需求的。

4 經驗總結

  • 宏定義看似很簡單,沒實踐出來的時候,有時候會想不通為什么會這么被展開?
  • 在gcc編譯器下查看宏定義被展開的內容使用的是-E選項。
  • C語言宏定義中的 “#” 和 “##” 是有特殊用法的,必須要用于帶參數的宏定義中,否則會報語法錯誤。
  • 留個疑問:為何加了一個中間宏函數轉了一道手,就能得到預期的內容?

5 參考鏈接

  • C語言的宏定義
  • 帶參數和不帶參數的宏定義

6 更多分享

架構師李肯

一個專注于嵌入式IoT領域的架構師。有著近10年的嵌入式一線開發經驗,深耕IoT領域多年,熟知IoT領域的業務發展,深度掌握IoT領域的相關技術棧,包括但不限于主流RTOS內核的實現及其移植、硬件驅動移植開發、網絡通訊協議開發、編譯構建原理及其實現、底層匯編及編譯原理、編譯優化及代碼重構、主流IoT云平臺的對接、嵌入式IoT系統的架構設計等等。擁有多項IoT領域的發明專利,熱衷于技術分享,有多年撰寫技術博客的經驗積累,連續多月獲得RT-Thread官方技術社區原創技術博文優秀獎,榮獲CSDN博客專家、CSDN物聯網領域優質創作者、2021年度CSDN&RT-Thread技術社區之星、RT-Thread官方嵌入式開源社區認證專家、RT-Thread 2021年度論壇之星TOP4、華為云云享專家(嵌入式物聯網架構設計師)等榮譽。堅信【知識改變命運,技術改變世界】!

歡迎關注我的github倉庫01workstation,日常分享一些開發筆記和項目實戰,歡迎指正問題。

同時也非常歡迎關注我的專欄,有問題的話,可以跟我討論,知無不答,謝謝大家。

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

    關注

    180

    文章

    7598

    瀏覽量

    136205
  • 宏定義
    +關注

    關注

    0

    文章

    50

    瀏覽量

    9001
  • RT-Thread
    +關注

    關注

    31

    文章

    1272

    瀏覽量

    39924
收藏 人收藏

    評論

    相關推薦

    RT-Thread學習筆記】使用scons命令生成靜態庫

    RT-Thread學習筆記】如何使用scons 命令中buildlib的生成靜態庫?
    的頭像 發表于 07-27 09:13 ?5860次閱讀
    【<b class='flag-5'>RT-Thread</b><b class='flag-5'>學習</b><b class='flag-5'>筆記</b>】使用scons命令生成靜態庫

    RT-ThreadC語言編碼規范

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

    RT-Thread Nano入門學習筆記

    RT-Thread Nano入門學習筆記
    發表于 11-26 12:36 ?20次下載
    <b class='flag-5'>RT-Thread</b> Nano入門<b class='flag-5'>學習</b><b class='flag-5'>筆記</b>

    RT-Thread 應用筆記 - RTC Alarm 組件的使用

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

    RT-Thread 內核學習筆記 - 理解defunct僵尸線程

    RT-Thread 內核學習筆記 - 內核對象rt_objectRT-Thread 內核學習筆記
    發表于 01-25 18:19 ?8次下載
    <b class='flag-5'>RT-Thread</b> 內核<b class='flag-5'>學習</b><b class='flag-5'>筆記</b> - 理解defunct僵尸線程

    RT-Thread 內核學習筆記 - 設備模型rt_device的理解

    RT-Thread 內核學習筆記 - 內核對象rt_objectRT-Thread 內核學習筆記
    發表于 01-25 18:19 ?8次下載
    <b class='flag-5'>RT-Thread</b> 內核<b class='flag-5'>學習</b><b class='flag-5'>筆記</b> - 設備模型<b class='flag-5'>rt</b>_device的理解

    RT-Thread 內核學習筆記 - 內核對象鏈表結構深入理解

    RT-Thread 內核學習筆記 - 內核對象rt_objectRT-Thread 內核學習筆記
    發表于 01-25 18:23 ?6次下載
    <b class='flag-5'>RT-Thread</b> 內核<b class='flag-5'>學習</b><b class='flag-5'>筆記</b> - 內核對象鏈表結構深入理解

    RT-Thread 內核學習筆記 - 內核對象初始化鏈表組織方式

    RT-Thread 內核學習筆記 - 內核對象rt_objectRT-Thread 內核學習筆記
    發表于 01-25 18:24 ?3次下載
    <b class='flag-5'>RT-Thread</b> 內核<b class='flag-5'>學習</b><b class='flag-5'>筆記</b> - 內核對象初始化鏈表組織方式

    RT-Thread 內核學習筆記 - 內核對象操作API

    RT-Thread 內核學習筆記 - 內核對象rt_objectRT-Thread 內核學習筆記
    發表于 01-25 18:26 ?7次下載
    <b class='flag-5'>RT-Thread</b> 內核<b class='flag-5'>學習</b><b class='flag-5'>筆記</b> - 內核對象操作API

    RT-Thread學習筆記 --(3)RT-Thread自動初始化機制分析

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

    RT-Thread學習筆記 RT-Thread的架構概述

    RT-Thread 簡介 作為名 RTOS 的初學者,也許你對 RT-Thread 還比較陌生。然而,隨著你的深入接觸,你會逐漸發現 RT-Thread 的魅力和它相較于其他同類型
    的頭像 發表于 07-09 11:27 ?4483次閱讀
    <b class='flag-5'>RT-Thread</b><b class='flag-5'>學習</b><b class='flag-5'>筆記</b> <b class='flag-5'>RT-Thread</b>的架構概述

    RT-Thread學習筆記】Makefile的FORCE

    RT-Thread學習筆記】十分鐘學會Makefile的FORCE
    的頭像 發表于 07-30 13:55 ?2465次閱讀
    【<b class='flag-5'>RT-Thread</b><b class='flag-5'>學習</b><b class='flag-5'>筆記</b>】Makefile的FORCE

    RT-Thread學習筆記】如何抓取終端的網絡報文

    RT-Thread學習筆記】如何抓取終端的網絡報文?
    的頭像 發表于 07-30 13:57 ?2746次閱讀
    【<b class='flag-5'>RT-Thread</b><b class='flag-5'>學習</b><b class='flag-5'>筆記</b>】如何抓取終端的網絡報文

    RT-Thread學習筆記】用memwatch排除內存泄露

    RT-Thread學習筆記】使用memwatch排除內存泄露
    的頭像 發表于 07-30 14:01 ?2240次閱讀
    【<b class='flag-5'>RT-Thread</b><b class='flag-5'>學習</b><b class='flag-5'>筆記</b>】用memwatch排除內存泄露

    基于RT-Thread Studio學習

    前期準備:從官網下載 RT-Thread Studio,弄個賬號登陸,開啟rt-thread學習之旅。
    的頭像 發表于 05-15 11:00 ?3825次閱讀
    基于<b class='flag-5'>RT-Thread</b> Studio<b class='flag-5'>學習</b>