细说cc中的宏(macro)和宏替换

上传人:自*** 文档编号:80682804 上传时间:2019-02-19 格式:DOC 页数:4 大小:65.30KB
返回 下载 相关 举报
细说cc中的宏(macro)和宏替换_第1页
第1页 / 共4页
细说cc中的宏(macro)和宏替换_第2页
第2页 / 共4页
细说cc中的宏(macro)和宏替换_第3页
第3页 / 共4页
细说cc中的宏(macro)和宏替换_第4页
第4页 / 共4页
亲,该文档总共4页,全部预览完了,如果喜欢就下载吧!
资源描述

《细说cc中的宏(macro)和宏替换》由会员分享,可在线阅读,更多相关《细说cc中的宏(macro)和宏替换(4页珍藏版)》请在金锄头文库上搜索。

1、细说C/C+中的宏(Macro)和宏替换宏(Macro),在C/C+中,是一个颇有争议的话题。在以前的老代码中,我们总是可以看到很多使用得很巧妙的宏,而在大多数的C+教材中,宏的使用都是不被推荐的,因为宏的使用比较容易产生BUG,这些BUG是由一些宏的边界效应(Side effect)所导致,而且这些BUG在调试的过程中都是很难发现的。到底该不该用宏?我的观点是,并不是因为它容易产生BUG就不用它,一定要学会如何用宏、何时用宏。很多时候,巧妙的使用宏,一方面可以减少代码量,一方面还可以提高代码效率。所以,我们现在要做的就是深入、全面了解宏相关的内容,只有充分的掌握了它,才会用好它!1. 预处理

2、命令(Preprocessor commands)(1) #define 用来定义一个预处理宏,编译时直接替换#define PI 3.1415926在代码中所有出现PI 的地方,都被替换为3.1415926,只是简单的替换,不做任何类型检查,因此,使用者必须确保类型的正确性。(2)#undef 用来取消已经定义过的一个宏#undef PI如果在之前定义过PI,那么,在当前文件中从上面这行代码开始,以及包含上面这行代码所在文件的所有文件中,PI都不再代表3.1415926(3)#include 用来引入一个要包含的文件#include在当前文件中引入stdio.h这个文件。(4)#if #en

3、dif , #if#else#endif, #if#elif#else#endif, 几种条件宏定义的方式,只有在指定的条件成立时才引入该条件块中的预编译语句。这些条件宏定义语句,常和defined搭配在一起使用,但没有必要一定要使用defined。#if defined(_DEBUG_)# define Msg(msg) printf(%sn, msg)#else# define Msg(msg)#endif上面的语句,只有在_DEBUG_宏定义的时候,Msg才会输出指定的字串信息。另一种比较常的用法是,用条件语句来注释代码:#if 0printf(This is commentedn);#

4、endif这样,在该条件语句块中的语句都将不会被执行。(5)#ifdef#endif, #ifdef#else#endif, #ifndef#endif, #ifndef#else#endif. 这些条件宏定义的用法,和(4)中提到的条件宏与defined搭配在一起的用法差不多。#ifdef _WIN32# define STRNCASECMP _strnicmp#else# define STRNCASECMP strncasecmp#endif上面的宏,定义了一个可跨平台的字符串比较函数,在windows平台上用_strnicmp()实现,在unix上用strncasecmp()实现。(6

5、)#,字符串替换,把跟在其后面的内容按字符串进行替换。#define PUTS(s) printf(%sn, #s)使用上面的宏,PUTS(a)的替换结果就是printf(%sn, a)(7)#,字符替换,把跟在其后面的内容按字符进行替换。#define PUT(c) printf(%cn, #c)使用上面的宏,PUT(a)的替换结果就是printf(%cn, c)(8)#,将两侧的两个token, 连接成为一个。#define DEFINE_SETTER(name, type, member) void Set#name(const type & arg) member = arg;

6、 DEFINE_SETTER(Age, int, m_nAge),相当于定义了一个这样的函数:void SetAge(const int & arg) m_nAge = arg;在成员变量很多的类中,为了保证比较好封装性,我们假定每个成员变量都是private的。这样我们就需要为每个成员实现对应的Setter和Getter,如果一个个去写,会有看上去很相似的函数,有很大的重复性的工作。此时,便可采用上面的宏的方式,一行搞定一个,看上去就代码比较简洁了。(10)#error用来输出编译时的一些出错信息。下面是一个名为Test.cpp的文件:#include #define SIZE 12

7、9#if (SIZE % 128) != 0#error SIZE must be a multiple of 128!#endifint main()对Test.cpp用 g+ -c Test.cpp命令编译,会得到如下错误信息:Test.cpp:6:2: error: #error “SIZE must be a multiple of 128!”(11)#line 用来暗示编译器,当前代码的这一行是由用户写的代码中某个文件中的某一行生成的。(12)#pragma 用来给编译器指定与实现相关的一些信息,在所有的预处理命令中,#pragma是最为复杂的,下面对其进行比较详细的说明:#prag

8、ma的使得语法为: #pragma para, 其中para为其参数,下面介绍一些常用的参数。A. #pragma message(“text”) 在编译信息输出窗口中输出text信息B. #pragma once 只要在头文件的最开始加入这条指令就能够保证头文件被编译一次,这条指令实际上在VC6中就已经有了,但是考虑到兼容性并没有太多的使用它。C. #pragma hdrstop 表示预编译头文件到此为止,后面的头文件不进行预编译。D. #pragma resource “*.dfm” 表示把*.dfm文件中的资源加入工程。*.dfm中包括窗体外观的定义。E. #pragma warning

9、( disable: 4507 34; once: 4385; error: 164 ),等价于:#pragma warning( disable: 4507 34 ) / 不显示4507和34号警告信息#pragma warning( once: 4385 ) / 4385号警告信息仅报告一次#pragma warning( error: 164 ) / 把164号警告信息作为一个错误。F. #pragma comment() 该指令将一个注释记录放入一个对象文件或可执行文件中。常用的lib关键字,可以帮我们连入一个库文件。如: #pragma comment(lib, “comctl32.

10、lib”)G. #pragma pack( n ) 该指令指定结构和联合成员的紧凑对齐。当使用#pragma pack ( n ) 时, 这里n 为1、2、4、8 或16。当使用#pragma pack时,按缺省设置进行对齐。还有一种加强型语法:#pragma pack( push | pop , identifier, n )2.预定义的宏(Predefined Macros)(1)_LINE_ 当前代码行的行号(整数)(2)_FILE_ 当前代码所在的文件的文件名(字符串)(3)_TIME_ 当前时间(hh:mm:ss)(4)_DATE_ 当前日期(Mmm dd yyyy)(5)_STDC_ 如果编译器的实现兼容ISO C,那么,该宏被定义为常量1(6)_STDC_VERSION_ C89:199409L; C99:199901L, otherwise, not defined(7)_cplusplus C+编译器会预定义这个宏,在标准C+中,它的值是版本号

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 其它办公文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号