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 <stdarg.h> 
#include <stdio.h>

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

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
C51中,并没有直接定义printf函数C51是一种嵌入式C编程语言,它是由Keil公司开发的用于8051系列单片机的开发工具。C51编译器提供了一组标准库函数,但并没有内置的printf函数。 然而,你可以使用C51提供的其他函数来实现类似的功能。例如,你可以使用串口通信函数来将数据发送到串口,并在终端或另一台设备上显示出来。 以下是一个示例代码,使用C51的串口通信函数实现类似printf函数的功能: ```c #include <reg51.h> void UART_Init() { // 设置串口通信参数 // ... } void UART_SendChar(char c) { // 发送一个字符到串口 // ... } void UART_SendString(char* str) { while (*str) { UART_SendChar(*str++); } } void main() { int num = 10; char str[20]; UART_Init(); sprintf(str, "The number is: %d\n", num); UART_SendString(str); } ``` 在上面的代码中,我们定义了UART_Init函数用于初始化串口通信参数,UART_SendChar函数用于发送单个字符到串口,UART_SendString函数用于发送字符串到串口。 在main函数中,我们使用sprintf函数将格式化的字符串存储到字符数组str中,然后调用UART_SendString函数将字符串发送到串口。 请注意,上述代码中的UART_Init、UART_SendChar和UART_SendString函数只是示例,实际的函数实现可能需要根据你的具体硬件和串口通信方式进行调整。 总结来说,C51并没有直接定义printf函数,但你可以使用C51提供的函数实现类似的功能,例如使用串口通信函数将数据发送到终端或其他设备上显示出来。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值