此处引用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. swiper轮播的slide高度自适应

    方式1:官方给的属性 autoHeight: true, //高度随内容变化 发现实际没效果 方式2:先定义了一个slide的高度数组, //设置slide父级高度 index为slide的索引 fu ...

  2. 求组合数的O(n^2)和O(n)解法及模板

    概率论中的组合数应该比较熟悉吧,在数论中组合数也具有重大意义,下面介绍组合数的解法: 方法一O(n^2): 利用公式(n,m)=(n-1,m-1)+(n-1,m): 模板: #include<c ...

  3. c++ 读入优化、输出优化模板

    0. 在有些输入数据很多的变态题中,scanf会大大拖慢程序的时间,cin就更慢了,所以就出现了读入优化.其原理就是一个一个字符的读入,输出优化同理,主要使用getchar,putchar函数. 1. ...

  4. 第九章 词典 (c)散列:散列函数

  5. c# 记录内容到txt文件

    string a= content;//采样结果 if (!File.Exists("e:\\newfile\\newtxt.txt")) { new FileStream(&qu ...

  6. 网页请求get方式

    方法都是博客中的大神写的,谢谢各路大神. 方法一:(亲测有效) //Get请求方式 private string RequestGet(string Url) { string PageStr = s ...

  7. JavaScript各种继承方式(二):借用构造函数继承(constructor stealing)

    一 原理 在子类的构造函数中,通过call ( ) 或 apply ( ) 的形式,调用父类的构造函数来实现继承. function Fruit(name){ this.name = name; th ...

  8. 【centos】centos安装配置samba

    因为我的centos为一台阿里云服务器,想和我本机(mac)进行文件共享.所以在我的阿里云上安装配置samba. 服务器环境:centos 7.3 本地环境:mac 第1步:首先查看是否已经安装过了s ...

  9. js关于去重的写法

    break和continue的区别和作用 break和continue都是用来控制循环结构的,主要是停止循环. 1.break 有时候我们想在某种条件出现的时候终止循环而不是等到循环条件为false才 ...

  10. Exploring the world of Android :: Part 2

    September 17th, 2009 by Tom van Zummeren | And I’m back! Reporting live on the glorious adventures i ...