常用C代码碎片:
1、函数参数接口
typedef int(*pfunc)(int x, int y) //pfunc是带两个参数,返回值为int
pfunc handler
2、宏函数、宏字符串连接
#define joiner(param1, param2) param1##param2
#define tostring(param) #param
#define UARTHANDLER(NAME) UART_##NAME##_recv_handler
#define UARTTASKHANDLER(NAME) RS485_##NAME##_task
#define UARTTASKSTRING(NAME) "RS485_"NAME"_task"
3、位赋值操作
typedef struct
{
u8 lv1:1;//故障等级1 u8类型的低位
u8 lv2:1;//故障等级2
u8 lv3:1;//故障等级3
u8 max_lv:2;//最高故障等级(单个故障)
u8 res:3;//保留 u8类型的高位
}SINGLE_FLV_FLAG_BIT;//单个故障等级标志位位域
4、统计二进制数中的个数
int func(int x) {
int countx = 0;
while(x) {
countx++;
x = x &(x-1);
}
return countx;
}
5、C++使用extern C的巧妙用法
#ifdef __cplusplus
# define MODBUS_BEGIN_DECLS extern "C" {
# define MODBUS_END_DECLS }
#else
# define MODBUS_BEGIN_DECLS
# define MODBUS_END_DECLS
#endif
MODBUS_BEGIN_DECLS
MODBUS_END_DECLS
6、字符串接收匹配到对应的字符串
int8_t recv_wait_for_resp(modbus_t *ctx, char *msg, uint16_t len, const char *resp) {
uint8_t i=0;
int16_t rc;
uint8_t resp_len = strlen(resp);
uint16_t msg_length = 0;
while(1)
{
rc = ctx->backend->recv(ctx, msg + msg_length, 1);
if (rc == 0) {
return 0;
}
msg_length += rc;
if(msg[msg_length-1] == resp[i])
{
if(i==(resp_len-1))
{
return msg_length;
}
i++;
}
else if(msg[msg_length-1] == resp[0])
{
i=1;
}
else
{
i=0;
}
if(msg_length >= len) {
return 0;
}
}
return 0;
}
7、字节数据转换为可打印字符串
// 如:{0xC8, 0x32, 0x9B, 0xFD, 0x0E, 0x01} --> "C8329BFD0E01"
// pSrc: 源数据指针
// pDst: 目标字符串指针
// nSrcLength: 源数据长度
// 返回: 目标字符串长度
int gsmBytes2String(const unsigned char* pSrc, char* pDst, int nSrcLength)
{
const char tab[]="0123456789ABCDEF"; // 0x0-0xf的字符查找表
UINT8 i ;
for(i=0; i<nSrcLength; i++)
{
// 输出低4位
*pDst++ = tab[*pSrc >> 4];
// 输出高4位
*pDst++ = tab[*pSrc & 0x0f];
pSrc++;
}
// 输出字符串加个结束符
*pDst = '\0';
// 返回目标字符串长度
return nSrcLength * 2;
}
8、
// 可打印字符串转换为字节数据
// 如:"C8329BFD0E01" --> {0xC8, 0x32, 0x9B, 0xFD, 0x0E, 0x01}
// pSrc: 源字符串指针
// pDst: 目标数据指针
// nSrcLength: 源字符串长度
// 返回: 目标数据长度
int gsmString2Bytes(const char* pSrc, unsigned char* pDst, int nSrcLength)
{
int i;
for(i=0; i<(nSrcLength+1); i+=2)
{
// 输出高4位
if(*pSrc>='0' && *pSrc<='9')
{
*pDst = (*pSrc - '0') << 4;
}
else
{
*pDst = (*pSrc - 'A' + 10) << 4;
}
pSrc++;
// 输出低4位
if(*pSrc>='0' && *pSrc<='9')
{
*pDst |= *pSrc - '0';
}
else
{
*pDst |= *pSrc - 'A' + 10;
}
pSrc++;
pDst++;
}
// 返回目标数据长度
return nSrcLength;
}
状态字符串描述与状态值
#define ENUM_ITEM(ITEM) ITEM,
#define ENUM_STRING(ITEM) #ITEM,
#define KEY_STATUS_ENUM(STATUS) \
STATUS(KS_RELEASE) /*稳定松开状态*/ \
STATUS(KS_PRESS_SHAKE) /*按下抖动状态*/ \
STATUS(KS_PRESS) /*稳定按下状态*/ \
STATUS(KS_RELEASE_SHAKE) /*松开抖动状态*/ \
STATUS(KS_NUM) /*状态总数(无效状态)*/ \
typedefenum
{
KEY_STATUS_ENUM(ENUM_ITEM)
}KEY_STATUS;
constchar* key_status_name[] = {
KEY_STATUS_ENUM(ENUM_STRING)
};