文件my_debug.c:
#define MY_DEBUG_C
#include "my_debug.h"
int __my_allow_debug_levels[MY_SECTION_END];
文件my_debug.h:
#ifndef MY_DEBUG_H
#define MY_DEBUG_H
#include// 模块功能号//这里需要根据实际情况扩展,有多少个需要输出调试信息的模块就定义多少个。
enum { MY_SECTION_FACT = 0,
MY_SECTION_nnn1,
MY_SECTION_nnn2,
MY_SECTION_nnnn, MY_SECTION_END,};
// 非my_debug.c文件的外部变量声明
//my_debug.c中定义了MY_DEBUG_C
#ifndef MY_DEBUG_C
extern int __my_allow_debug_levels[MY_SECTION_END];
#endif
// (内部使用) 判断"SECTION"模块功能号是否允许"DEBUG_LEVEL"等级的调试信息输出
//函数fact中使用了宏my_debug,它又使用了本宏
#define __my_unallow_debug(SECTION, DEBUG_LEVEL) \
( DEBUG_LEVEL > __my_allow_debug_levels[SECTION] )
// (内部使用) 调试信息输出函数
//函数fact中使用了宏my_debug,它又使用了本宏
#define __my_debug(FORMAT, ARG...) \
printf("%s:%d %s: " FORMAT, __FILE__, __LINE__, __FUNCTION__, ##ARG)
// 初始化"SECTION"模块功能号的调试等级
//main函数中使用两次
#define my_init_debug_levels(SECTION, ALLOW_DEBUG_LEVEL) \
( __my_allow_debug_levels[SECTION] = ALLOW_DEBUG_LEVEL )
// 调试信息输出函数,该信息为"SECTION"模块功能号"DEBUG_LEVEL"等级的调试信息
//函数 fact中使用
#define my_debug(SECTION, DEBUG_LEVEL) \
( __my_unallow_debug(SECTION, DEBUG_LEVEL) ) ? (void) 0 : __my_debug
#endif //MY_DEBUG_H
文件fact.c(含示例模块函数fact()):
#include <stdio.h>
#include <stdlib.h>
#include "my_debug.h"
int fact(int n)
{
int i, f = 1;
for( i=1; i<=n; i++)
{
f *= i;
my_debug(MY_SECTION_FACT, 250)("i=%d ; f=%d\n", i, f);
}
return f;
}
int main(int argc, char *argv[])
{
if ( argc < 2 )
{
my_init_debug_levels(MY_SECTION_FACT, 0);
}
else
{
my_init_debug_levels(MY_SECTION_FACT, atoi(argv[1]));
}
printf( "4!=%d\n", fact(4) );
return 0;
}
要使用上述文件,先得根据功能模块的数目扩展my_debug.h中的“模块功能号”枚举类型,然后在程序相应位置中调用宏定义my_init_debug_levels 初始化相应模块的调试等级,在所有需要输出调试信息的位置如下编写即可。
my_debug(MY_SECTION_FACT, 250)("i=%d ; f=%d/n", i, f);
文件my_debug.c和my_debug.h与fact.c一起编译。