3338|4

2015

帖子

0

TA的资源

纯净的硅(中级)

楼主
 

C51用宏定义代替printf函数 [复制链接]

问题提出
有时候我们想用宏定义来决定是编译debug版本的代码还是release的代码,dubug版本的代码会通过printf打印调试信息,release版本的代码则不会。我们总不能对每一条printf都这样写:


#if _DEBUG_
printf("hello world!");
#endif

这样子实在是太麻烦了!万一要各个地方都要打印,会使版面看起来很乱。


GCC编译器解决方法
我后来想到一个方法,编译器为GCC,可以使用宏定义代替printf函数,由于printf是可变参数的函数,这里就要用到变參宏(…和__VA_ARGS__)。
在头文件下写此代码


#define _DEBUG_ 1

#if _DEBUG_
#define PR(...) printf(__VA_ARGS__)
#else
#define PR(...)
#endif
后面需要打印调试信息的时候使用PR宏就可以了,如果需要release版本,不打印调试信息,就把DEBUG设置为0,编译出来的程序就不会打印调试信息了。


keil C51中的问题


  gcc编译器与c51是两个不同的编译器,所以C语言编译的标准也是不同的。


   如果C51使用GCC编译标准宏定义代替printf函数,你的代码将会报错,C51的缓存内存是有限的,宏定义是 不允许有定义不定参数函数的。我想了好久,它不给宏定义不定参数函数,但却可以使用printf不定参数函数,我可不可以跳过不定参数函数呢?





#define _debug_  1
#if _debug_
#define debug_printf   printf
#else
#define debug_printf  //
#endif
我巧妙的利用define  代替的特性,如果_debug_等于1时,debug_printf 等于printf  ,打印正常输出 ,但_debug_等于0时,打印将关闭,debug_printf 将等于 // ,编译时后面打印的将被注释掉。


经常在实际的调试过程中,使用最基本的调试方法printf,但是常常需要在print函数中使用参数__FILENAME__、__FUNCTION__、__LINE__,特别是大型的项目中,感觉在编码时重复写入这几个参数有些繁琐,所以很自然的想到了宏定义,当然你也可以参照printf函数写自己的My_Printf函数,但是不想费周折就使用宏定义吧!代码如下:

环境 标准C99,GNC

#define PRT(...) printf("Filename %s, Function %s, Line %d > ", __FILE__, __FUNCTION__, __LINE__); \
                            printf(__VA_ARGS__); \
                            printf("\n");

测试代码:

#include
#include

#define PRT(...) printf("Filename %s, Function %s, Line %d > ", __FILE__, __FUNCTION__, __LINE__); \
                            printf(__VA_ARGS__); \
                            printf("\n");

int main()
{  
   int a =0;
   PRT("a");
    PRT("hello, %d ", 10);
    PRT("%d, %s, %d", 10, "dafdsa", 20);
    return 0;
}


测试结果:

root@ubuntu:/home/ybq/Desktop# gcc printf.c -o printf
root@ubuntu:/home/ybq/Desktop# ./printf
Filename printf.c, Function main, Line 22 > a
Filename printf.c, Function main, Line 23 > hello, 10
Filename printf.c, Function main, Line 24 > 10, dafdsa, 20

文章记录在这里,没有什么技术含量,但是挺实用的,在这里给大家分享一下,希望它能给大家带来便利!

推荐使用这个宏:

#define DVR_PRT(format,...)  printf("[File:"__FILE__", Line:%d]  "format, __LINE__, ##__VA_ARGS__)

#define PRT(format,...)  printf("[File:%s, Line:%d] "format, __FILE__, __LINE__, ##__VA_ARGS__)
该技巧可以用在单片机C语言开发上,切换版本非常方便。
keil环境下如何重定向printf到串口,可以参考这里。

最新回复

[attach]466383[/attach]   详情 回复 发表于 2020-3-25 11:18
 
点赞 关注

回复
举报

1371

帖子

6

TA的资源

版主

沙发
 
不错,谢谢分享!
 
个人签名专注智能产品的研究与开发,专注于电子电路的生产与制造……QQ:2912615383,电子爱好者群: void
 

回复

71

帖子

0

TA的资源

宇宙尘埃

板凳
 
谢谢分享!了解一下
 
个人签名FTP
 
 

回复

30

帖子

0

TA的资源

一粒金砂(中级)

4
 
瞎扯吧,我刚试了c51不支持__VA_ARGS__
 
 
 

回复

30

帖子

0

TA的资源

一粒金砂(中级)

5
 

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表