Micro definition ---C语言中宏定义使用总结

来源:互联网 发布:vs2015 mysql 编辑:程序博客网 时间:2024/05/18 16:40

Micro definition ---C语言中宏定义使用总结

1、用于定义代码中不会变化的常量

#define  MAX_LEN  1024

2、用于封装某些常用的代码块(不是函数,类似于函数的作用)

#define  MAX(x,y) (((x)>(y)) ? (x) : (y)) #define  MIN(x,y) (((x) < (y)) ? (x) : (y)) 

比如这样的写法:

#define    DRAW_TEXT(f, t, d, use_bg)                                \if (d)                                                               \ {                                                                    \    CvSize _size;                                                    \      cvGetTextSize(t, &font, &_size, NULL);                           \      if (use_bg)                                                      \      {                                                                \          cvRectangle(f, cvPoint(0, f->height),                        \                      cvPoint(_size.width + 5,                         \                              f->height - _size.height * 2),           \                      CV_RGB(255, 0, 0), CV_FILLED, 8, 0);             \      }                                                                \      cvPutText(f, t, cvPoint(2, f->height - _size.height / 2),        \                &font, CV_RGB(255,255,0));                             \      d--;                                                             \  }  
再比如这种:

#define DRAW_RECTS(f, d, rw, ro)                                   \{                                                                  \     cvRectangle(f, POINTS(rw), CV_RGB(255, 0, 0), 1, 8, 0);        \      cvRectangle(f, POINTS(ro), CV_RGB(0, 255, 0), 1, 8, 0);        \      cvRectangle(d, POINTS(rw), cvScalarAll(255),  1, 8, 0);        \      cvRectangle(d, POINTS(ro), cvScalarAll(255),  1, 8, 0);        \  } 

对于有多个操作,多行代码最好使用do{...}while(0)包含,防止意外的错误。

例如:

有问题的定义:

#define DUMP_WRITE(addr,nr) {memcpy(bufp,addr,nr); bufp += nr;} 
应该使用的定义: 

#difne DO(a,b) do{a+b;a++;}while(0)  
例如:

if(addr)    DUMP_WRITE(addr,nr);else    do_somethong_else(); 
宏展开以后变成这样:

if(addr)    {memcpy(bufp,addr,nr); bufp += nr;}; else    do_something_else(); 
gcc 在碰到else前面的“;”时就认为if语句已经结束,因而后面的else不在if语句中。而采用do{} while(0)的定义,在任何情况下都没有问题。

有do{...}while(0)时的情况:

if(addr)    do{          memcpy(bufp, addr, nr);          bufp += nr;      }    while(0);else    do_something_else();
3、用于防止头文件被重复引用

#ifndef  _FILE_HEAD_H_#define  _FILE_HEAD_H_#endif
还有另外一种方式也可以达到目的(依赖于编译器,不推荐),有些编译器不支持

#pragma once
4、消除某些头文件中已经定义的宏参数

#ifdef  MICRO_NAME#undef  MICRO_NAME#endif
5、用于注释和打开代码块

#if 0/*your code, want not use*/#endif
如果需要打开代码块,只需将0改成1即可。

若工程中有多处这样的代码,需同时打开或同时关闭,可以这样。

#define  DEBUG_FLAG 0#if DEBUG_FLAG/*your code*/#endif#if DEBUG_FLAG/*your code*/#endif#if DEBUG_FLAG/*your code*/#endif
6、使用宏进行跟踪调试,记录日志

ANSI标准说明了五个预定义的宏名。它们是:

__LINE__ __FILE__         /*在MSVC编译器中__FILE__ 在Debug模式下是带全路径的文件名(full path name)  Release模式下仅有文件名(file name)*/                 /*在vac gcc编译器中__FILE__ 仅代表文件名(file name)*/__DATE__ __TIME__ __STDC__
C++中还定义了 __cplusplus
如果编译器不是标准的,则可能仅支持以上宏名中的几个,或根本不支持。记住编译程序也许还提供其它预定义的宏名。
__LINE__ 及 __FILE__ 宏指示,#line指令可以改变它的值,简单的讲,编译时,它们包含程序的当前行数和文件名。
__DATE__ 宏指令含有形式为月/日/年的串,表示源文件被翻译到代码时的日期。

__TIME__ 宏指令包含程序编译的时间。时间用字符串表示,其形式为: 分:秒

__STDC__ 宏指令的意义是编译时定义的。一般来讲,如果__STDC__已经定义,编译器将仅接受不包含任何非标准扩展的标准C/C++代码。如果实现是标准的,则宏__STDC__含有十进制常量1。如果它含有任何其它数,则实现是非标准的。

 __cplusplus 与标准c++一致的编译器把它定义为一个包含至少6为的数值。与标准c++不一致的编译器将使用具有5位或更少的数值。 可以定义宏,例如:
当定义了_DEBUG,输出数据信息和所在文件所在行

#ifdef _DEBUG#define DEBUGMSG(msg,date)printf(msg);printf(“%d%d%d”,date,_LINE_,_FILE_) #else#define DEBUGMSG(msg,date)#endif 

7、关于#pragma

上面有提到过#pragma once可以用于避免头文件被重复引用。

#pragma comment则更强大:

①windows环境添加lib静态库

#pragma comment(lib, "ws2_32.lib")

②windows环境设置控制台程序连接入口

#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )/*设置入口地址, 隐藏控制台窗口*/

总结:

1.宏名和参数的括号间不能有空格;
2.宏替换只作替换,不做计算,不做表达式求解;
3. 函数调用在编译后程序运行时进行,并且分配内存。宏替换在编译前进行,不分配内存;
4.函数只有一个返回值,利用宏则可以设法得到多个值;
5.宏展开使源程序变长,函数调用不会;
6.宏展开不占运行时间,只占编译时间,函数调用占运行时间(分配内存、保留现场、值传递、返回值);
7.使用条件编译可以使目标程序变小,运行时间变短;
8.预编译使问题或算法的解决方案增多,有助于我们选择合适的解决方案。




0 0
原创粉丝点击