0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

怎么利用C可变参数和宏定义来实现自己的日志系统

汽车电子技术 来源:IOT物联网小镇 作者:道哥 2023-02-14 13:50 次阅读

嵌入式应用的开发过程中,日志系统是非常重要的!

特别是在生产环节出现了偶发性的、与当前的执行环境相关的bug的时候,

如果没有日志系统来追踪问题,很难进行问题重现。

因此,实现一个自己的日志系统是很有帮助、很必要的。

在软件模型上,一般是把日志系统编译成库文件。

应用程序直接调用库中提供的API接口函数,即可记录日志信息

那么实现自己的日志系统需要有3个问题需要处理:

(1)日志API函数的设计。

(2)日志信息的缓存。

(3)日志信息的持久化,也就是写入到本地文件系统。

这篇文章主要说明第一个问题:日志API函数的设计。

先上代码:

图片

图片

测试

图片

图片

知识点

1.字符串字面量的拼接

C语言中,字符串的拼接有很多种方法:memcpy,strcpy,strcat,sprintf等等。

在代码19行,使用了C语言中的字符串字面量拼接的方式,把 " %s:%d(%s) \"" format "\"\\n"3个字符串拼接成一个字符串。

补充一下:

在日志系统代码中,有些地方需要格式化字符串。

使用sprintf是最方便的,但是也是效率最低的!

也可以利用一些第三方的库来实现字符串格式化,比如:fmtlib,facebook 的 folly format,google的 Abseil StrFormat。

当然,最好的方式是自己实现格式化特定类型的数据,可以显著的提高日志系统的吞吐量,下一篇文章再说说这部分代码。

2.可变参数

大家都知道,printf函数就是通过可变参数机制来实现的。

可变参数可以这样定义和使用:

(1)不带参数名

图片

(2)带参数名

图片

20行代码用 __VA_ARGS__ 来代表宏定义参数中的三个点(...),也就是可变参数。



再来说说“##”。

如果调用:debug2("code = %d", 100); 这样调用没有问题。

如果调用:debug2("hello"); 这里调用时,在format后面没有传入任何参数,那么就会编译错误,因为在宏替换之后变成了 printf("hello",),第一个参数之后多了一个逗号,因此报错。

如果调用:debug3("hello, world!"); 这样就没有问题,因为debug3中在可变参数__VA_ARGS__的前面有“##”,当编译器发现没有传入参数时,会自动把format后面的逗号去掉,所以编译OK。

3.宏定义中的#和##

#的作用就是在预处理的时候,把宏参数进行“字符串化”,例如:

图片

##的作用就是在预处理的时候,把两个宏参数进行“粘合”,例如:

图片

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 日志系统
    +关注

    关注

    0

    文章

    7

    浏览量

    6992
  • 生产
    +关注

    关注

    0

    文章

    121

    浏览量

    14032
  • 嵌入式应用
    +关注

    关注

    0

    文章

    58

    浏览量

    18432
收藏 人收藏

    评论

    相关推荐

    C语言定义使用技巧

    写好C语言,漂亮的定义很重要,使用定义可以防止出错,提高可移植性,可读性,方便性等等。下面列举一些成熟软件中常用的
    发表于 07-29 09:35 1093次阅读

    C语言定义与枚举类型知识

    定义的标识符不占内存,只是一个临时的符号,预编译后这个符号就不存在了。在简单的程序使用带参数定义可完成函数调用的功能,又能减少系统开销,
    发表于 10-11 17:34 1539次阅读

    可变参数函数的实现原理

    ,或者其它方式。在C语言标准头文件stdarg.h里面已经为可变函数定义了几个,使用这些也可以实现
    发表于 10-21 22:18

    C语言定义中#和##的作用

    定义的递归展开。可以通过中间的转换的实现参数
    发表于 08-23 18:22

    C语言——可变参数问题.

    来区别不同函数参数的调用,但它还是不能表示任意数量的函数参数。   问题:printf的实现   请问,如何自己实现printf函数,如何处
    发表于 04-20 15:17

    XC32编译器是否支持中的可变参数列表?

    我试图在实现可变参数列表,但是得到以下错误:error:u VA_ARGS_只能出现在C99可变
    发表于 03-16 10:24

    C语言中可变参数定义

    C语言的可变参数定义。//可变参数用...表示
    发表于 07-14 07:43

    C语言定义使用技巧

    写好C语言,漂亮的定义很重要,使用定义可以防止出错,提高可移植性,可读性,方便性 等等。下面列举一些成熟软件中常用得
    发表于 11-13 12:04 36次下载

    不带参数定义是什么?不带参数定义的资料介绍详细过程概述

    c语言中有一个定义,其中有一类就是不带参数定义
    发表于 09-04 15:38 5次下载

    可变参数__ VA_ARGS__的用法

    可变参数__VA_ARGS__的用法
    的头像 发表于 03-20 09:26 1w次阅读
    <b class='flag-5'>可变</b><b class='flag-5'>参数</b>的<b class='flag-5'>宏</b>__ VA_ARGS__的用法

    文件系统中的日志系统是如何实现

    日志 本文聊聊文件系统中的日志系统,来看一个简单的日志系统
    的头像 发表于 09-29 11:04 2154次阅读
    文件<b class='flag-5'>系统</b>中的<b class='flag-5'>日志</b><b class='flag-5'>系统</b>是如何<b class='flag-5'>实现</b>的

    C语言中的定义

    #define命令是C语言中的一个定义命令,它用来将一个标识符定义为一个字符串,该标识符被称为名,被
    的头像 发表于 09-28 16:05 3375次阅读
    <b class='flag-5'>C</b>语言中的<b class='flag-5'>宏</b><b class='flag-5'>定义</b>

    c语言定义可以嵌套吗?

    c语言定义可以嵌套吗? C语言定义可以嵌套,也就是一个
    的头像 发表于 09-04 17:38 3067次阅读

    c语言带参数定义

    定义 2. 带参数定义 3. 带可变参数
    的头像 发表于 09-04 17:45 2323次阅读

    如何实现一个自己的printf函数代码?

    C语言中,可变参数函数和可变参数都允许函数或
    发表于 09-06 14:20 894次阅读
    如何<b class='flag-5'>实现</b>一个<b class='flag-5'>自己</b>的printf函数代码?