RM新时代网站-首页

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

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

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

C語言必備知識(shí)編譯預(yù)處理

CHANBAEK ? 來源:小李的創(chuàng)客實(shí)驗(yàn)室 ? 作者: 初出茅廬的小李 ? 2023-12-01 18:27 ? 次閱讀

C語言必備知識(shí)編譯預(yù)處理

編譯預(yù)處理就是在編譯源代碼之前進(jìn)行的一系列處理,將源程序中的一些特殊命令進(jìn)行展開或處理,生成擴(kuò)展的源代碼。這些特殊命令通常以“#”開頭,占單獨(dú)的行,語句尾部不需要加分號(hào)。

宏定義

(#define)是一種常見的編譯預(yù)處理指令,用于定義宏,實(shí)現(xiàn)代碼的簡化和重用。

文件包含(#include)用于在源文件中引入其他文件的內(nèi)容,方便代碼模塊化和復(fù)用。

條件編譯

(#if, #else, #endif等)允許根據(jù)條件選擇性地編譯部分代碼,提高代碼的靈活性。

在預(yù)處理階段,這些指令會(huì)被解釋和處理,生成經(jīng)過預(yù)處理的源代碼,然后再經(jīng)過編譯、匯編、鏈接等步驟生成最終的可執(zhí)行文件。這個(gè)過程有助于提高代碼的可維護(hù)性和可移植性。

書寫格式

以“#”開頭、占單獨(dú)行、語句尾不加分號(hào)。這樣的規(guī)范有助于編譯器正確解釋和處理這些指令,同時(shí)也使得代碼更加清晰易讀。這樣的一致性規(guī)范有助于維護(hù)代碼時(shí)的可讀性和可理解性。

宏定義的例子

// 定義常量

#include < stdio.h >

#define MAX_SIZE 100
#define PI 3.1415926

// 簡化代碼
#define SQUARE(x) ((x) * (x))
#define MAX(a, b) ((a) > (b) ? (a) : (b))


#define DEBUG   //只要定義了該宏 DEBUG_PRINT就會(huì)起作用 沒有定義則不起作用 

// 字符串拼接

//#define CONCAT_STR(a,b) a##b dev平臺(tái)用不了 linux未測試
#define CONCAT_STR(a,b) a b

// 條件編譯
#ifdef DEBUG
    #define DEBUG_PRINT(msg) printf("Debug: %sn", msg)
#else
    #define DEBUG_PRINT(msg)
#endif




int main(void) 
{
	
	printf("5的平方是%drn",SQUARE(5));
	printf("MAX(2,3)返回較大的一個(gè)數(shù)是%drn",MAX(2,3)) ;
	DEBUG_PRINT("調(diào)試信息"); 
	printf("%srn", CONCAT_STR("你好", "World"));  // 這里會(huì)被展開為 printf("%srn", "你好, " "World");
}

這里踩到了一個(gè)坑............. dev里這個(gè)##符號(hào)竟然不能使用!看了這個(gè)博主的文章才明白 https://blog.csdn.net/leon1741/article/details/78149881,致謝致敬圖片

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

圖片
在這里插入圖片描述

宏定義使用注意事項(xiàng)

使用宏定義時(shí)需要注意一些事項(xiàng),以確保代碼的可讀性和正確性。以下是一些宏定義的注意事項(xiàng):

  1. 括號(hào)的使用:
    在宏定義中,為了避免優(yōu)先級(jí)問題,通常在宏的參數(shù)和整體表達(dá)式外部都使用括號(hào)。例如:

    #define SQUARE(x) ((x) * (x))
    

    這樣可以確保在使用時(shí)不會(huì)出現(xiàn)預(yù)期之外的行為。

  2. 避免副作用:
    在宏中避免使用具有副作用的表達(dá)式,因?yàn)楹晔呛唵蔚奈谋咎鎿Q,可能導(dǎo)致意外的行為。

    // 避免這樣的宏定義
    #define INCREMENT(x) x++
    
  3. 使用大寫字母:
    為了與變量和函數(shù)名區(qū)分,宏的名稱通常使用大寫字母。

    #define MAX_SIZE 100
    
  4. 多行宏的注意:
    如果宏跨越多行,確保在每行的末尾使用反斜杠 連接,以避免語法錯(cuò)誤。

    #define PRINT_SUM(a, b) 
        do { 
            int sum = (a) + (b); 
            printf("Sum: %dn", sum); 
        } while(0)
    
  5. 參數(shù)的使用:
    宏參數(shù)的使用要小心,確保在宏展開時(shí)不會(huì)導(dǎo)致預(yù)期之外的結(jié)果。

    // 不要這樣使用,可能導(dǎo)致問題
    #define SQUARE(x) x * x
    
  6. 條件編譯:
    在使用條件編譯時(shí),確保相關(guān)的宏定義和取消定義都是正確的。

    #ifdef DEBUG
        // ...
    #endif
    

總體來說,清晰、簡潔、避免副作用是設(shè)計(jì)宏定義時(shí)的關(guān)鍵原則。良好的宏定義可以提高代碼的可讀性和可維護(hù)性。

單片機(jī)中可以使用預(yù)編譯來區(qū)分代碼版本

如果定義了REG_CODE 這個(gè)宏且其結(jié)果是1那么就是寄存器版本代碼否則就是庫函數(shù)版本代碼

void LED_Config(void)
{
	#if (REG_CODE)
	
	RCC- >AHB1ENR |= 1< 2;      //GPIOC的時(shí)鐘開關(guān)

	GPIOC- >MODER &= ~(3< 2*4);//把89位清00 PC4
	GPIOC- >MODER |=  (1< 2*4);//只是把第89位置01
	
	GPIOC- >MODER &= ~(3< 2*5);//把10 11位清00 PC5
	GPIOC- >MODER |=  (1< 2*5);//只是把第89位置01
	
	GPIOC- >MODER &= ~(3< 2*6);//把11 12位清00 PC6
	GPIOC- >MODER |=  (1< 2*6);//只是把第89位置01
	
	GPIOC- >MODER &= ~(3< 2*7);//把89位清00  PC7
	GPIOC- >MODER |=  (1< 2*7);//只是把第89位置01
	
	GPIOC- >OTYPER &= ~(1< 4); //推挽模式//0xFFFF FFEF 
	GPIOC- >OTYPER &= ~(1< 5);
	GPIOC- >OTYPER &= ~(1< 6);
	GPIOC- >OTYPER &= ~(1< 7);
	
	
	//假設(shè)輸出狀態(tài) 燈的開關(guān)
	GPIOC- >ODR |=  (1< 4)| (1< 5)|(1< 6) |(1< 7);  //默認(rèn)全關(guān)
	printf("寄存器代碼...rn");
	#else
	printf("LED庫函數(shù)代碼...rn");
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
	
    GPIO_InitTypeDef  GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode   = GPIO_Mode_OUT;
	GPIO_InitStruct.GPIO_OType  = GPIO_OType_PP;
	GPIO_InitStruct.GPIO_Pin    = GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
	GPIO_InitStruct.GPIO_PuPd   = GPIO_PuPd_NOPULL;
	GPIO_InitStruct.GPIO_Speed  = GPIO_High_Speed;
	
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	
	
	#endif
	
}

至此,預(yù)編譯相關(guān)的知識(shí)點(diǎn)就介紹完了。

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

    關(guān)注

    180

    文章

    7604

    瀏覽量

    136685
  • 源代碼
    +關(guān)注

    關(guān)注

    96

    文章

    2945

    瀏覽量

    66730
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4779

    瀏覽量

    68521
  • 編譯
    +關(guān)注

    關(guān)注

    0

    文章

    657

    瀏覽量

    32852
  • 預(yù)處理
    +關(guān)注

    關(guān)注

    0

    文章

    33

    瀏覽量

    10478
收藏 人收藏

    評(píng)論

    相關(guān)推薦

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

    1.基礎(chǔ)知識(shí)(1)C語言常用的預(yù)處理命令——typedef具體可見C語言基礎(chǔ)語法
    發(fā)表于 07-14 07:10

    c語言預(yù)處理命令以什么開頭

    c語言預(yù)處理命令以什么開頭,目前我并沒有windows軟件編寫經(jīng)驗(yàn),對(duì)C語言的應(yīng)用也僅限于各種單片機(jī)的編程,所以對(duì)
    發(fā)表于 07-20 07:00

    介紹一下C語言預(yù)處理知識(shí)與宏定義原理

    系統(tǒng)平臺(tái)上的gcc)前言本篇文章將會(huì)向大家介紹一下C語言預(yù)處理知識(shí)、宏定義、函數(shù)、以及編譯執(zhí)行程序所需的靜態(tài)鏈接庫和動(dòng)態(tài)鏈接庫的一些原理,
    發(fā)表于 02-11 06:35

    C語言編譯預(yù)處理

    在將一個(gè)C源程序轉(zhuǎn)換為可執(zhí)行程序的過程中, 編譯預(yù)處理是最初的步驟. 這一步驟是由預(yù)處理器(preprocessor)來完成的. 在源流程序被編譯
    發(fā)表于 09-20 18:17 ?47次下載

    基于51單片機(jī)--C語言預(yù)處理總結(jié)

    編譯預(yù)處理器是C語言編譯器的一個(gè)重要組成部分。很好的利用C
    發(fā)表于 08-17 10:48 ?1080次閱讀

    C程序設(shè)計(jì)教程之如何進(jìn)行編譯預(yù)處理

    預(yù)處理C 語言的一個(gè)重要功能,它由預(yù)處理程序負(fù)責(zé)完成。所謂預(yù)處理是指在進(jìn)行編譯的第一遍掃描(
    發(fā)表于 11-02 15:47 ?5次下載

    C語言程序設(shè)計(jì)教程之如何進(jìn)行函數(shù)與編譯預(yù)處理資料概述

    本文檔的主要內(nèi)容詳細(xì)介紹的是C語言程序設(shè)計(jì)教程之如何進(jìn)行函數(shù)與編譯預(yù)處理資料概述主要內(nèi)容包括了:1 函數(shù)概述2 函數(shù)定義與調(diào)用3 局部變量和全局變量4 變量的生存期和存儲(chǔ)類別5
    發(fā)表于 12-10 17:16 ?4次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>程序設(shè)計(jì)教程之如何進(jìn)行函數(shù)與<b class='flag-5'>編譯</b><b class='flag-5'>預(yù)處理</b>資料概述

    C語言程序設(shè)計(jì)教程之編譯預(yù)處理的詳細(xì)資料說明

    本文檔的主要內(nèi)容詳細(xì)介紹的是C語言程序設(shè)計(jì)教程之編譯預(yù)處理的詳細(xì)資料說明主要內(nèi)容包括了:1.宏定義 2.文件包含 3.條件編譯
    發(fā)表于 01-08 14:19 ?2次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>程序設(shè)計(jì)教程之<b class='flag-5'>編譯</b><b class='flag-5'>預(yù)處理</b>的詳細(xì)資料說明

    淺析VerilogHDL編譯系統(tǒng)的預(yù)處理

    。在Verilog HDL語言編譯時(shí),特定的編譯指令在整個(gè)編譯過程中有效(編譯過程可跨越多個(gè)文件),直到遇到其他不同的
    發(fā)表于 03-26 16:10 ?762次閱讀

    C語言預(yù)處理命令的分類和工作原理詳細(xì)說明

    器,故在閱讀或開發(fā) C/C++ 程序過程中,可能會(huì)接觸大量的預(yù)處理指令。 1、預(yù)處理指令及分類 C/C
    發(fā)表于 11-25 10:34 ?18次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>預(yù)處理</b>命令的分類和工作原理詳細(xì)說明

    C語言預(yù)處理指令及分類

    C/C++ 程序中的源代碼中包含以 # 開頭的各種編譯指令,這些指令稱為預(yù)處理指令。預(yù)處理指令不屬于 C
    的頭像 發(fā)表于 11-29 10:14 ?2256次閱讀

    C語言宏定義與預(yù)處理、函數(shù)和函數(shù)庫

    系統(tǒng)平臺(tái)上的gcc)前言本篇文章將會(huì)向大家介紹一下C語言預(yù)處理知識(shí)、宏定義、函數(shù)、以及編譯執(zhí)行程序所需的靜態(tài)鏈接庫和動(dòng)態(tài)鏈接庫的一些原理,
    發(fā)表于 12-07 21:06 ?2次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>宏定義與<b class='flag-5'>預(yù)處理</b>、函數(shù)和函數(shù)庫

    C語言-預(yù)處理(#define、#if...)

    C語言程序里,出現(xiàn)的#開頭的代碼段都屬于預(yù)處理。 預(yù)處理:是在程序編譯階段就執(zhí)行的代碼段。
    的頭像 發(fā)表于 08-14 10:13 ?2449次閱讀

    為什么C語言要進(jìn)行編譯

    為什么我們編寫的C語言要進(jìn)行編譯?什么是編譯?編譯時(shí)發(fā)生了什么? 機(jī)器無法理解我們編寫的C
    的頭像 發(fā)表于 11-24 15:47 ?1321次閱讀
    為什么<b class='flag-5'>C</b><b class='flag-5'>語言</b>要進(jìn)行<b class='flag-5'>編譯</b>

    C語言有哪些預(yù)處理操作?

    C語言預(yù)處理是在編譯之前對(duì)源代碼進(jìn)行處理的階段,它主要由預(yù)處理器完成。
    的頭像 發(fā)表于 12-08 15:40 ?611次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>有哪些<b class='flag-5'>預(yù)處理</b>操作?
    RM新时代网站-首页