linux c 常用代码

常用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;
}

 

 

 

9、状态字符串描述与状态值

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

 

10、/*参考CJson代码有浮点数比较,因为浮点数单独采用==或!=判断是不准的,浮点数本质上是无限接近值,所以要用以下函数去判断比较*/

int compare_double(double a, double b)
{
double maxVal = fabs(a) > fabs(b) ? fabs(a) : fabs(b);
return (fabs(a - b) <= maxVal * DBL_EPSILON);
}

11、

计算大于等于 x 的最小的 2 的幂

#define B2(x) ((x) | ((x) >> 1))
#define B4(x) (B2(x) | (B2(x) >> 2))
#define B8(x) (B4(x) | (B4(x) >> 4))
#define B16(x) (B8(x) | (B8(x) >> 8))
#define B32(x) (B16(x) | (B16(x) >> 16))
#define NEXT_POWER_OF_2(x) (B32((x)-1) + 1)  

 

posted @ 2022-07-20 08:57  cogitoergosum  阅读(111)  评论(0编辑  收藏  举报