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 once4、消除某些头文件中已经定义的宏参数
#ifdef MICRO_NAME#undef MICRO_NAME#endif5、用于注释和打开代码块
#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*/#endif6、使用宏进行跟踪调试,记录日志
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.预编译使问题或算法的解决方案增多,有助于我们选择合适的解决方案。
- Micro definition ---C语言中宏定义使用总结
- C语言学习笔记(八) -宏定义 Macro Definition
- C语言宏定义总结
- C语言宏定义总结
- c语言宏定义总结
- c语言宏定义总结
- 20个C语言中常用宏定义总结
- C语言中宏定义#define用法总结。
- 20个C语言中常用宏定义总结
- 20个C语言中常用宏定义总结
- 关于c语言中宏定义的总结
- c语言重复定义 multiple definition of `Recusion'
- c语言宏定义中##连接符和#的使用
- C语言宏定义中do while(0)的使用
- C语言中使用空的宏定义的作用
- C 语言宏定义用法总结
- C语言宏定义方法总结
- C语言宏定义高级用法总结
- ***UVA12657 Boxes in a Line ACM解题报告(链表)
- AngularJS的MVC浅谈
- 我的UFO观
- 贪吃蛇游戏
- ssh学习总结1
- Micro definition ---C语言中宏定义使用总结
- 在Windows下安装Python的lxml库
- 获取iOS设备唯一标识
- HTML+CSS总结
- Android系统中消息机制的一些开发总结
- 01(CodeforcesC水平)CQU新生周末狂欢赛 N - Win or Freeze
- Java的split函数切分空串和标点
- Qt 延迟
- Linux 的开机启动流程详解