c 预处理 命令详解

上传人:小** 文档编号:89123264 上传时间:2019-05-18 格式:DOC 页数:4 大小:17.50KB
返回 下载 相关 举报
c 预处理 命令详解_第1页
第1页 / 共4页
c 预处理 命令详解_第2页
第2页 / 共4页
c 预处理 命令详解_第3页
第3页 / 共4页
c 预处理 命令详解_第4页
第4页 / 共4页
亲,该文档总共4页,全部预览完了,如果喜欢就下载吧!
资源描述

《c 预处理 命令详解》由会员分享,可在线阅读,更多相关《c 预处理 命令详解(4页珍藏版)》请在金锄头文库上搜索。

1、C 预处理命令详解C预处理命令详解2010-04-1519:08常用的预处理命令如下l#define定义一个预处理宏l#undef取消宏的定义l#include包含文件命令l#include_next与#include相似,但它有着特殊的用途l#if编译预处理中的条件命令,相当于C语法中的if语句l#ifdef判断某个宏是否被定义,若已定义,执行随后的语句l#ifndef与#ifdef相反,判断某个宏是否未被定义l#elif若#if,#ifdef,#ifndef或前面的#elif条件不满足,则执行#elif之后的语句,相当于C语法中的else-ifl#else与#if,#ifdef,#ifnd

2、ef对应,若这些条件不满足,则执行#else之后的语句,相当于C语法中的elsel#endif#if,#ifdef,#ifndef这些条件命令的结束标志.l#line标志该语句所在的行号l将宏参数替代为以参数值为内容的字符窜常量l将两个相邻的标记(token)连接为一个单独的标记常用的预处理命令中编程技巧:1)宏定义语句中可以利用来换行.e.g.#defineONE1/*ONE=1*/等价于:#defineONE1#defineerr(flag,msg)if(flag)printf(msg)等价于:#defineerr(flag,msg)if(flag)printf(msg)2)函数宏之后的参

3、数要用括号括起来e.g.#definemul(x,y)(x)*(y)看看下面这个例子e.g.#definemul(x,y)x*ymul(1,2+2);将被扩展为:1*2+2同样,整个标记串也应该用括号引用起来e.g.#definemul(x,y)(x)*(y)sizeofmul(1,2.0)将被扩展为sizeof1*2.03)函数宏的参数问题e.g.#defineinsert(stmt)stmtinsert(a=1;b=2;)相当于在代码中加入a=1;b=2.insert(a=1,b=2;)就有问题了预处理器会提示出错函数宏的参数个数不匹配.预处理器把,视为参数间的分隔符.insert(a=1

4、,b=2;)可解决上述问题.4do-while(0)语句#defineswap(x,y)dounsignedlong_temp=x;x=y;y=_tmpwhile(0)swap(1,2);将被替换为dounsignedlong_temp=1;1=2;2=_tmpwhile(0);Linux内核源代码中对这种do-while(0)语句有这广泛的应用.5)宏可以被多次定义,前提是这些定义必须是相同的.这里的相同要求先后定义中空白符出现的位置相同,但具体的空白符类型或数量可不同,比如原先的空格可替换为多个其他类型的空白符可为tab键e.g.#defineNULL0#defineNULL/*nullp

5、ointer*/0上面的重定义是相同的,但下面的重定义不同#definefun(x)x+1#definefun(x)x+1或:#definefun(y)y+1如果多次定义时,再次定义的宏内容是不同的,gcc会给出NAMEredefined警告信息.6)在gcc中,可在命令行中指定对象宏的定义e.g.$gcc-Wall-DMAX=100-otmptmp.c/-D是前缀相当于在tmp.c中添加#defineMAX100.那么,如果原先tmp.c中含有MAX宏的定义,那么再在gcc调用命令中使用-DMAX,会出现什么情况呢?-若-DMAX=1,则正确编译.-若-DMAX的值被指定为不为1的值,那么g

6、cc会给出MAX宏被重定义的警告,MAX的值仍为1.注意若在调用gcc的命令行中不显示地给出对象宏的值,那么gcc赋予该宏默认值(1),如:-DVAL=-DVAL=17)#define所定义的宏的作用域宏在定义之后才生效,若宏定义被#undef取消,则#undef之后该宏无效.并且字符串中的宏不会被识别e.g.#defineTWO2/sum=ONE+TWO/*sum=1+2*/charc=TWO/*那么c=TWO,不是等于2!*/8)使用#if可以提升代码的可移植性-针对不同的平台使用执行不同的语句.也经常用于大段代码注释.e.g.#if0一大段代码;#endif9)如果常量表达式为一个未定义

7、的宏,那么它的值被视为0.#ifMACRO_NON_DEFINED/相当于#if0在判断某个宏是否被定义时,应当避免使用#if,因为该宏的值可能就是被定义为0.而应当使用#ifdef或#ifndef.10)#ifdef或#ifndef经常用于避免头文件的重复引用#ifndef_FILE_H_#define_FILE_H_#includefile.h#endif代表如果还未定义_FILE_H_,就执行下面两行代码,也就宏定义_FILE_H_引用头文件。11)defined(name):它有返回值,若宏被定义,则返回1,否则返回0.它与#if,#elif,#else结合使用来判断宏是否被定义,乍一

8、看好像它显得多余,因为已经有了#ifdef和#ifndef.但defined用于在一条判断语句中声明多个判别条件#ifdefined(VAX)&defined(UNIX)&!defined(DEBUG)12)我们对#include_next不太熟悉.#include_next仅用于特殊的场合.它被用于头文件中(#include既可用于头文件中,又可用于.c文件中来包含其他的头文件.而且包含头文件的路径比较特殊从当前头文件所在目录之后的目录来搜索头文件.比如头文件的搜索路径一次为A,B,C,D,E.#include_next所在的当前头文件位于B目录,那么#include_next使得预处理器从

9、C,D,E目录来搜索#include_next所指定的头文件.13)下面列出一些标准C中常见的预定义对象宏其中也包含gcc自己定义的一些预定义宏_LINE_当前语句所在的行号,以10进制整数标注._FILE_当前源文件的文件名,以字符串常量标注._DATE_程序被编译的日期,以Mmmddyyyy格式的字符串标注._TIME_程序被编译的时间,以hh:mm:ss格式的字符串标注,该时间由asctime返回._STDC_如果当前编译器符合ISO标准,那么该宏的值为1_STDC_VERSION_如果当前编译器符合C89,那么它被定义为199409L,如果符合C99,那么被定义为199901L._ST

10、DC_HOSTED_如果当前系统是本地系统(hosted),那么它被定义为1.本地系统表示当前系统拥有完整的标准C库.gcc定义的预定义宏_OPTMIZE_如果编译过程中使用了优化,那么该宏被定义为1._OPTMIZE_SIZE_同上,但仅在优化是针对代码大小而非速度时才被定义为1._VERSION_显示所用gcc的版本号.要想看到gcc所定义的所有预定义宏,可以运行:$cpp-dM/dev/null14)的使用用于在宏扩展之后将宏定义参数转换为以此参数为内容的字符串常量.e.g.#defineTEST(a,b)printf(#a#b=%dn,(a)(b);那么调用TEST(10,9)的效果是printf(109=%dn,(10)(9);注意只针对紧随其后的token有效!用于将它前后的两个token组合在一起转换成以这两个token为内容的字符串常量.注意前后必须要有token.e.g.#defineTYPE(type,n)type#n之后调用TYPE(int,a)=1;TYPE(long,b)=1999;将被替换为inta=1;longb=1999;

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 商业/管理/HR > 管理学资料

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