C51用宏定义代替printf函数

问题提出

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

#if _DEBUG_
printf("hello world!");
#endif
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

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

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到串口,可以参考这里。

你可能感兴趣的:(编程)