C語言#和##連接符在項(xiàng)目中的應(yīng)用(漂亮)
之前看見ST官方一個(gè)老外的風(fēng)格,看完之后大贊??纯此窃趺磳懙?
#ifndef RINGBUFF_HDR_H
#define RINGBUFF_HDR_H
#ifdef __cplusplus
extern "C" {
#endif
#include <string.h>
#include <stdint.h>
/**
* \defgroup RINGBUFF Ring buffer
* \brief Generic ring buffer manager
* \{
*/
/* --- Buffer unique part starts --- */
/**
* \brief Buffer function/typedef prefix string
*
* It is used to change function names in zero time to easily re-use same library between applications.
* Use `#define BUF_PREF(x) my_prefix_ ## x` to change all function names to (for example) `my_prefix_buff_init`
*
* \note Modification of this macro must be done in header and source file aswell
*/
#define BUF_PREF(x) ring ## x
/* --- Buffer unique part ends --- */
/**
* \brief Buffer structure
*/
typedef struct {
uint8_t* buff; /*!< Pointer to buffer data.
Buffer is considered initialized when `buff != NULL` and `size` */
size_t size; /*!< Size of buffer data. Size of actual buffer is `1` byte less than value holds */
size_t r; /*!< Next read pointer. Buffer is considered empty when `r == w` and full when `w == r - 1` */
size_t w; /*!< Next write pointer. Buffer is considered empty when `r == w` and full when `w == r - 1` */
} BUF_PREF(buff_t);
uint8_t BUF_PREF(buff_init)(BUF_PREF(buff_t)* buff, void* buffdata, size_t size);
void BUF_PREF(buff_free)(BUF_PREF(buff_t)* buff);
void BUF_PREF(buff_reset)(BUF_PREF(buff_t)* buff);
/* Read/Write functions */
size_t BUF_PREF(buff_write)(BUF_PREF(buff_t)* buff, const void* data, size_t btw);
size_t BUF_PREF(buff_read)(BUF_PREF(buff_t)* buff, void* data, size_t btr);
size_t BUF_PREF(buff_peek)(BUF_PREF(buff_t)* buff, size_t skip_count, void* data, size_t btp);
/* Buffer size information */
size_t BUF_PREF(buff_get_free)(BUF_PREF(buff_t)* buff);
size_t BUF_PREF(buff_get_full)(BUF_PREF(buff_t)* buff);
/* Read data block management */
void * BUF_PREF(buff_get_linear_block_read_address)(BUF_PREF(buff_t)* buff);
size_t BUF_PREF(buff_get_linear_block_read_length)(BUF_PREF(buff_t)* buff);
size_t BUF_PREF(buff_skip)(BUF_PREF(buff_t)* buff, size_t len);
/* Write data block management */
void * BUF_PREF(buff_get_linear_block_write_address)(BUF_PREF(buff_t)* buff);
size_t BUF_PREF(buff_get_linear_block_write_length)(BUF_PREF(buff_t)* buff);
size_t BUF_PREF(buff_advance)(BUF_PREF(buff_t)* buff, size_t len);
#undef BUF_PREF /* Prefix not needed anymore */
/**
* \}
*/
#ifdef __cplusplus
}
#endif
#endif /* RINGBUFF_HDR_H */
這個(gè)老外實(shí)現(xiàn)的是一個(gè)環(huán)形緩沖,然而他巧妙的將ring這個(gè)字串去掉,最后閱讀代碼看到的是非常整齊的:
BUF_PREF(buffer_init)
BUF_PREF(buff_free)
BUF_PREF(buff_write)
BUF_PREF(buff_read)
等等。。。
接下來看看到底是怎么用的:
#define BUF_PREF(x) ring ## x
"##" 表示將左邊的字符串和右邊的字符串連接起來,但是只能黏貼C語言除了關(guān)鍵字以外的合法標(biāo)識符 于是上面展開的效果如下:
ring_buffer_init
ring_buffer_free
ring_buffer_write
ring_buffer_read
等等。。。
既然知道了原理,那我在項(xiàng)目上可以這么來用。
之前,你寫個(gè)LED驅(qū)動(dòng)或者別的可能是這樣的,定義了這么多個(gè)函數(shù)
void led_device_open(void);
void led_device_close(void);
uint8_t led_device_read(void);
uint8_t led_device_write(uint8_t status);
。。。
看起來很統(tǒng)一,我一眼看出這是一個(gè)LED的操作方法,但操作一個(gè)LED不就是open,close,read,write方法嗎?
我們可以讓它看起來更優(yōu)雅:
#define LED_CLASS(x) led_device_ ## x
void LED_CLASS(open)(void);
void LED_CLASS(close)(void);
uint8_t LED_CLASS(read)(void);
uint8_t LED_CLASS(write)(uint8_t status);
如果我寫另外一個(gè)驅(qū)動(dòng),也是一樣有open,close,read,write接口,假設(shè)是個(gè)FLASH設(shè)備。那還是一樣的:
#define FLASH_CLASS(x) flash_device_ ## x
void FLASH_CLASS(open)(void);
void FLASH_CLASS(close)(void);
uint8_t FLASH_CLASS(read)(void);
uint8_t FLASH_CLASS(write)(uint8_t status);
看起來舒服多了!Good!
那么##和#又有什么區(qū)別呢?
##剛剛已經(jīng)說了,是黏貼字符串
而#表示的是將參數(shù)轉(zhuǎn)換為字符串
下面寫一個(gè)跟#相關(guān)的例子:
#include <stdio.h>
#define Print(x) printf("%s %d\n",#x,x);
int main(void)
{
Print(100);
return 0 ;
}
運(yùn)行結(jié)果:
公眾號粉絲福利時(shí)刻
這里我給大家申請到了福利,本公眾號讀者購買小熊派開發(fā)板可享受9折優(yōu)惠,有需要購買小熊派的朋友,淘寶搜索即可,跟客戶說你是公眾號:嵌入式云IOT技術(shù)圈 的粉絲,立享9折優(yōu)惠!
往期精彩
C語言字符串的另類用法
別瞎找了,你要的C語言經(jīng)典示例都在這~
C語言表驅(qū)動(dòng)法編程實(shí)踐(精華帖,建議收藏并實(shí)踐)
嵌入式C語言代碼優(yōu)化方案(深度好文,建議花時(shí)間研讀并收藏)
若覺得本次分享的文章對您有幫助,隨手點(diǎn)[在看]
并轉(zhuǎn)發(fā)分享,也是對我的支持。
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!