连字符 c语言,C语言#和##连接符在项目中的应用(漂亮)

原标题:C语言#和##连接符在项目中的应用(漂亮)

之前看见ST官方一个老外的风格,看完之后大赞。看看他是怎么写的:

#ifndef RINGBUFF_HDR_H

#define RINGBUFF_HDR_H

#ifdef __cplusplus

extern "C" {

#endif

#include

#include

/**

* 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 */

这个老外实现的是一个环形缓冲,然而他巧妙的将ring这个字串去掉,最后阅读代码看到的是非常整齐的:

BUF_PREF(buffer_init)

BUF_PREF(buff_free)

BUF_PREF(buff_write)

BUF_PREF(buff_read)

等等。。。

接下来看看到底是怎么用的:

#define BUF_PREF(x) ring ## x

"##" 表示将左边的字符串和右边的字符串连接起来,但是只能黏贴C语言除了关键字以外的合法标识符 于是上面展开的效果如下:

ring_buffer_init

ring_buffer_free

ring_buffer_write

ring_buffer_read

等等。。。

既然知道了原理,那我在项目上可以这么来用。

之前,你写个LED驱动或者别的可能是这样的,定义了这么多个函数

void led_device_open(void);

void led_device_close(void);

uint8_t led_device_read(void);

uint8_t led_device_write(uint8_t status);

。。。

看起来很统一,我一眼看出这是一个LED的操作方法,但操作一个LED不就是open,close,read,write方法吗?

我们可以让它看起来更优雅:

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

如果我写另外一个驱动,也是一样有open,close,read,write接口,假设是个FLASH设备。那还是一样的:

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

那么##和#又有什么区别呢?

##刚刚已经说了,是黏贴字符串

而#表示的是将参数转换为字符串

下面写一个跟#相关的例子:

#include

#define Print(x) printf("%s %dn",#x,x);

int main(void)

{

Print(100);

return 0 ;

}

运行结果:

芯片之家精选文章合集 (一):收藏起来慢慢看

请戳右下角,给我一点在看!返回搜狐,查看更多

责任编辑:

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值