此处引用csdn博客。链接如下、

http://blog.csdn.net/cp1300/article/details/7773239

http://blog.csdn.net/aobai219/article/details/6092292

我们在写程序的时候,总是或多或少会加入一些printf之类的语句用于输出调试信息,但是printf语句有个很不方便的地方就是当我们需要发布程序的时候要一条一条的把这些语句删除,而一旦需要再次调试的时候,这些语句又不得不一条条的加上,这给我们带来了很大的不便,浪费了我们很多的时间,也造成了调试的效率低下。所以,很多人会选择使用宏定义的方式来输出调试语句。

作者通过两文的阅读,总结如下,并添加了自己的观点。

引言

首先说明的是 printf("123!\n""!""243");

语法正确,即输出等同printf("123!\n!243");

但是不似乎等同于printf("123!\n","!","243");

正文

1

假如有如下定义

#define EEPROM_ERROR(fmt,...)          printf("<<-EEPROM-ERROR->> "fmt"\n",##__VA_ARGS__)

‘ … ’指可变参数。这类宏在被调用时,它(这里指‘ … ’)被表示成零个或多个符号,包括里面的逗号,一直到到右括弧结束为止。当被调用时,在宏体( macro body )中,那些符号序列集合将代替里面的 保留名__VA_ARGS__ 标识符。如果可变参数被忽略或为空,‘ ## ’操作将使预处理器( preprocessor )去除掉它前面的那个逗号,这样当宏定义调用没有变参时候,可以宏替换时候没有错误的逗号。

调用时候,使用如下语句

EEPROM_ERROR("a= %d,b=%d,c=%d",a,b,c);

这时替换结果为    "a= %d,b=%d,c=%d" 与 fmt

a,b,c   与  ... (即__VA_ARGS__)

替换后相当于printf("<<-EEPROM-ERROR->> ""a= %d,b=%d,c=%d""\n",a,b,c);

2

假如有如下定义

#define EEPROM_INFO(fmt,arg...)           printf("<<-EEPROM-INFO->> "fmt"\n",##arg)

调用方法与1相同。不同的是,去掉了保留名__VA_ARGS__

3

为了使printf作为的调试信息更具体,将以上的调试方案更进一步

3.1

ANSI C标准中有几个标准预定义宏(也是常用的):

__LINE__:在源代码中插入当前源代码行号;

__FILE__:在源文件中插入当前源文件名;

3.2

在有些时候,\n并没有输出回车(环境为,win10+stc串口助手+stm32f429)。需要使用0x0d,0x0a之类的输出回车。所以使用了\r\n作为一个回车效果

3.3

有如下定义:

#define EEPROM_ERROR(fmt,arg...)          printf("\r\n<<-EEPROM-ERROR->> \r\n""LIFE NAME:"__FILE__ "\r\n""LINE:%d\r\n"fmt"\r\n\n",__LINE__,##arg)

调用如下:

EEPROM_ERROR("answer is c= %d c=%d c= %d",d,d,d);//假设c变量为uint8_t类型,值为6,并假设使用在第49行调用

输出结果为下:

<<-EEPROM-ERROR->>
LIFE NAME:..\User\main.c
LINE:49
answer is c= 6 c=6 c= 6

4

为了可以打开和关闭调试信息,可以将宏定义修改为:

#define EEPROM_ERROR(fmt,arg...)          //printf("\r\n<<-EEPROM-ERROR->> \r\n""LIFE NAME:"__FILE__ "\r\n""LINE:%d\r\n"fmt"\r\n\n",__LINE__,##arg)

这样子,在整个工程中的通过宏定义方案输出的调试信息全部消失。而不是去使用#ifdef之类的宏定义开关语句开关宏定义

单片机一种简便的printf调试方案。的更多相关文章

  1. 一种绕过PTRACE反调试的办法

    Linux 系统gdb等调试器,都是通过ptrace系统调用实现.Android加固中,ptrace自身防止调试器附加是一种常用的反调试手段. 调试时一般需要手工在ptrace处下断点,通过修改ptr ...

  2. 在VC下显示JPEG、GIF格式图像的一种简便方法

    在VC下显示JPEG.GIF格式图像的一种简便方法 一. 引言  JPEG图像压缩标准随然是一种有损图像压缩标准,但由于人眼视觉的不敏感,经压缩后的画质基本没有发生变化,很快便以较高的压缩率得到了广泛 ...

  3. 移动端调试 — Pure|微信环境调试方案|App环境调试方案

    Pure 详细参见: 中文文档:http://leeluolee.github.io/2014/10/24/use-puer-helpus-developer-frontend/ 源码:https:/ ...

  4. TCP/UDP Socket调试工具提供了TCP Server,TCP Client,UDP Server,UDP Client,UDP Group 五种Socket调试方案。

    一.TCP通信测试: 1)   创建TCP Server: 选中左方的TCP Server, 然后点击”创建”按钮,软件弹出监听端口输入框 输入监听端口后,即创建了一个在指定端口上进行监听的TCP S ...

  5. 两种方法实现asp.net方案的前后端数据交互(aspx文件、html+ashx+ajax)

    一个HTML页面只能显示HTML代码信息,不能与数据库进行数据的交互.asp.net方案提供了网页与数据库交互的方法,这里举出两种:①aspx文件 ②ashx文件+ajax技术 一.创建数据库 这里以 ...

  6. VC2010 MFC中实现printf调试功能,即MFC程序利用控制台输出调试信息。

    1.在项目自动生成的stdafx.h文件中添加下面头文件 #include <io.h> #include <fcntl.h> #include <stdio.h> ...

  7. 通用对象池ObjectPool的一种简易设计和实现方案

    对象池,最简单直接的作用当然是通过池来减少创建和销毁对象次数,实现对象的缓存和复用.我们熟知的线程池.数据库连接池.TCP连接池等等都是非常典型的对象池. 一个基本的简易对象池的主要功能实现我认为应该 ...

  8. 三种主流的WebService实现方案(REST/SOAP/XML-RPC)简述及比较

    目前知道的三种主流的Web服务实现方案为:REST:表象化状态转变 (软件架构风格)SOAP:简单对象访问协议 XML-RPC:远程过程调用协议 简单介绍: REST:表征状态转移(Represent ...

  9. [原创]一种Unity2D多分辨率屏幕适配方案

    此文将阐述一种简单有效的Unity2D多分辨率屏幕适配方案,该方案适用于基于原生开发的Unity2D游戏,即没有使用第三方2D插件,如Uni2D,2D toolkit等开发的游戏,NGUI插件不受这个 ...

随机推荐

  1. preg_match一些问题

    <?php$string = 'The quick brown fox jumps over the lazy dog.';$patterns = array();$patterns[0] =  ...

  2. awk技巧 nginx access.log

    1.1 介绍 awk其名称得自于它的创始人 Alfred Aho .Peter Weinberger 和 Brian Kernighan 姓氏的首个字母.实际上 AWK 的确拥有自己的语言: AWK ...

  3. NumPy 统计函数

    NumPy 统计函数 NumPy 提供了很多统计函数,用于从数组中查找最小元素,最大元素,百分位标准差和方差等. 函数说明如下: numpy.amin() 和 numpy.amax() numpy.a ...

  4. 1、str.join() 2、fromkeys() 3、深浅拷贝 4、set()

    1. 补充基础数据类型的相关知识点 1. str. join() 把列表变成字符串 2. 列表不能再循环的时候删除. 因为索引会跟着改变 3. 字典也不能直接循环删除. 把要删除的内容记录在列表中. ...

  5. label标签的显示和隐式关联问题

    按钮的html <!-- 学校 --> <div class="layui-inline"> <label class="layui-for ...

  6. 微信小程序开发——小程序API获取用户位置及异常流处理完整示例

    前言: 小程序需要添加一个定位功能,主要的就是获取用户位置的经纬度,然后根据用户经纬度进行一些判断操作. 在小程序提供的Api中,获取用户定位信息的主要Api是 wx.getLocation(obj) ...

  7. Volley超时重试机制

    基础用法 Volley为开发者提供了可配置的超时重试机制,我们在使用时只需要为我们的Request设置自定义的RetryPolicy即可. 参考设置代码如下: int DEFAULT_TIMEOUT_ ...

  8. 用Python监听鼠标和键盘事件

    PyHook是一个基于Python的“钩子”库,主要用于监听当前电脑上鼠标和键盘的事件.这个库依赖于另一个Python库PyWin32,如同名字所显示的,PyWin32只能运行在Windows平台,所 ...

  9. docker搭建lnmp(一)

    因为安装过程中涉及到一些修改配置文件的步骤,由于刚尝试不太会,所以这里都是通过安装好后,进入容器修改配置,最后退出重启容器. 目录结构 docker ├── mysql │   └── dockerf ...

  10. springboot 日志1

    技术交流群: 816227112 Spring Boot在所有内部日志中使用Commons Logging,但是默认配置也提供了对常用日志的支持,如:Java Util Logging,Log4J,  ...