C語言巨集定義高階用法總結
1、巨集定義函式頭 或字串連結
#define Function(name) void Func##name(void)
使用舉例
Function(mytest)
{
}
編譯器回編譯成
void Funcmytest(void)
{
}
2、多行巨集定義並在巨集定義中進行函式呼叫
使用舉例:
#define DSPI0_RX 0
#define DSPI1_RX 1
#define DSPI2_RX 2
#define DSPI3_RX 3
#define DSPI4_RX 4
void Spi_LLD_IsrRxDma_DSPI();
#define SPI_LLD_ISRRXDMA_DSPI_N_SRV(MCU_DMA_CHANNEL_n_SOURCE) \
if(MCU_DMA_CHANNEL_n_SOURCE == DSPI0_RX)\
{\
Spi_LLD_IsrRxDma_DSPI();\
}\
else if(MCU_DMA_CHANNEL_n_SOURCE == DSPI1_RX)\
{\
Spi_LLD_IsrRxDma_DSPI(); \
}\
else if(MCU_DMA_CHANNEL_n_SOURCE == DSPI2_RX)\
{\
Spi_LLD_IsrRxDma_DSPI();\
}\
else if(MCU_DMA_CHANNEL_n_SOURCE == DSPI3_RX)\
{\
Spi_LLD_IsrRxDma_DSPI();\
}\
else if(MCU_DMA_CHANNEL_n_SOURCE == DSPI4_RX)\
{\
Spi_LLD_IsrRxDma_DSPI();\
}
根據MCU_DMA_CHANNEL_n_SOURCE值的不同調用不同的函式。
3、空指標定義
#define NULL_PTR ((void *)0)
4、變數或返回值巨集定義指明型別和對應模組的使用技巧
舉例說明,常變數
typedef usigned char uint8;
typedef uint8 Adc_ChannelType;
#define CONST(consttype, memclass) const consttype
STATIC CONST(Adc_ChannelType, ADC_CONST) AdcGroup_10_Assignment_PB_2_1[4] =
{//AdcGroup_10
0U,
1U,
2U,
3U,
};
//Adc_ChannelType表明陣列元素為ADC通道型別,屬於ADC模組的常變數。
再例如:普通變數宣告
#define VAR(vartype, memclass) vartype
VAR(Adc_ChannelType, ADC_VAR) chId;
5、巨集定義實現斷言
舉例說明:
#define ASSERT(condition, message) {\
if(!(condition)){\
logError("Assertion failed:",#condition,message);\
exit(EXIT_FAILURE);\
}\
}
6、在嵌入式開發中,利用#define 和 typedef聯合使用,將地址常量變為結構體變數,並使用“.”運算子訪問結構體變數成員。
使用舉例
typedef volatile union
{
struct
{
unsigned int ECCENLDRAM : 1;
unsigned int ECCENDTAG : 1;
unsigned int ECCENSPRAM : 1;
unsigned int ECCENPTAG : 1;
unsigned int ECCENPMU : 1;
unsigned int ECCENPRAM : 1;
unsigned int ECCENCMEM : 1;
unsigned int ECCENCAN : 1;
unsigned int ECCENERAY : 1;
unsigned int : 23;
} B;
int I;
unsigned int U;
} SCU_ECCCON_type;
SCU_ECCCON_type SCU_ECCCON_Test;
#define SCU_ECCCON (*( SCU_ECCCON_type *) 0xffff10000)
#define SCU_ECCCON_Test_ECCENERAY (SCU_ECCCON.B.ECCENERAY)
//那麼直接對SCU_ECCCON_Test_ECCENERAY巨集進行操作就是對結構體變數SCU_ECCCON的B成員的ECCENERAY位進行操作。
//注意該案例中的結構體為變數定義的方法。
待續。。。。