VC预处理命令 第6页
#i nclude
path_spec是一个前面有目录说明的任选文件名。这个文件名必须命名一个现存文件。
path_spec的语法依赖于编译该程序的操作系统。
这两种语法格式都导致用已说明的包含文件的全部内容来替换该指令。两种格式的区别在于路径未完整指定时预处理器搜索头文件的顺序。
语法格式 动作
引号格式 这种格式指示预处理器先在包含#i nclude语句的文件的相同目录内搜索,然后在任何包括该文件的目录中搜索。随后预处理器沿着/I编译器选项指定的路径搜索,最后是在INCLUDE环境变量说明的路径搜索
尖括号格式 这种格式指示预处理器首先在/I编译器选项指定的路径中搜索包含文件。然后在INCLUDE环境变量说明的路径中搜索
一旦预处理器找到指定文件,它就立即停止搜索。如果用双引号给出一个明确完整的包含文件的路径,预处理器将只搜索该路径规格而忽略标准目录。
如果在双引号间的文件名不是一个完整的路径规格,预处理器将先搜索“父”文件的目录。父文件是一个包含#i nclude指令的文件。例如,如果你把名称为file2的文件包括在一个名称为file1的文件中,file1就是父文件。
包含文件可被嵌套;这指的是一个#i nclude指令出现在以另一个#i nclude指令命名的文件里。例如,以上的文件file2,可包含文件file3,在这种情况下,file1是file2的父文件,而且是file3的祖父文件。
当包含文件嵌套时,目录搜索首先由父文件的目录开始,然后,搜索祖父文件的目录。
因此,搜索从包含当前处理源文件的目录开始,若文件未找到,搜索就转到/I编译器选项指定的目录,最后搜索include环境变量指定的目录。
下面的例子给出使用尖括号的文件包括:
#i nclude
这个例子把名称为STDIO.H的文件内容加入到源程序中。尖括号指示预处理器在搜索完/I编译器选项说明的目录之后,搜索STDIO.H的环境变量指定的目录。下面的例子给出用引号格式的文件包括:#i nclude "defs.h"
这个例子把DEFS.H指定的文件内容加入源程序。双引号标记意味着预处理器首先搜索包含父源文件的目录。
包含文件的嵌套可高达10层,只要在处理嵌套的#i nclude指令时,预处理器就会不断地把包含文件加入到最初的源文件中。
Microsoft特殊处
为了定位可包括源文件,预处理器首先搜索/I编译器选项指定的目录。若/I选项未给定或已失败,预处理器就用INCLUDE环境变量搜索尖括号内的包含文件。INCLUDE环境变量和/I编译器选项可包含用分号分开的多个路径。若在/I选项的部分或在INCLUDE环境变量里有多于一个的目录,预处理器将以它们出现的顺序对它们进行搜索。
例如,命令:
CL /ID:\MSVC\INCLUDE MYPROG.C
导致预处理器在目录D:\MSVC\INCLUDE中搜索诸如STDIO.H的包含文件。命令:SET INCLUDE=D:\MSVC\INCLUDE
CL MYPROG.C
有相同的作用。如果所有搜索都失败了,将产生一个致命编译错误。
如果用包括一个冒号的路径(例如,F:\MSVC\SPECIAL\INCL\TEST.H)来完整地说明一个包含文件的文件名,预处理器将沿此路径搜索。
对于指定为#i nclude "path_spec"的包含文件,目录搜索将从父文件的目录开始,然后搜索祖父文件的目录。因此,搜索将从包含当前处理的#i nclude指令的源文件的目录开始,如果没有祖父文件或文件未找到,搜索将继续,就像文件名包括在尖括号中一样。
Microsoft特殊处结束
#line指令
#line指令告诉预处理器将编译器内部存储的行号和文件名转变为一个给定的行号和文件名。编译器使用该行号和文件名指出编译过程中发现的错误。行号一般指的是当前输入行,文件名指当前输入文件。每处理一行,行号就增1。
语法
#line
数字序列 “文件名”opt
数字序列的值可以是任何整型常数。宏替换可在预处理语言符号中执行,但结果必须求值为正确的语法。文件名可以是任意字符的组合,且应括在双引号(“”)间。如果省略文件名,则前面的文件名保持不变。
你可以通过编写一个#line指令来改动源行号和文件名。翻译器使用行号和文件名来确定预定义宏__FILE_ _和_ _LINE_ _的值。你可以使用这些宏把自描述错误消息加入到程序文本中。有关这些宏的更多信息参见预定义的宏。
__FILE_ _宏扩展成内容为用双引号(“”)括起的文件名的一个字符串。
如果你改变行号和文件名,编译器将忽略原有的值,用新值继续处理。#line指令通常被程序生成器用来生成指向最初源程序的错误消息,而不是生成程序。下面的例子用于说明#line以及_ _LINE_ _和_ _FILE_ _宏。在这个语句中,内部存储的行号设置为151,文件名改为copy.c。
#line 151 "copy.c"
在这个例子中,若一个给定的“断言”(assertion)不为真,则宏ASSERT使用预定义宏__LINE_ _和_ _FILE_ _打印出一个关于源文件的错误消息。
#define ASSERT(cond)
if( !(cond) ) \
{ printf("assertion error line %d, file(%s)\n",\
__LINE_ _,_ _FILE_ _); }
Null指令
空预处理器指令是一行中一个单独的数字标号(#),无任何作用。
语法
#
#undef指令
正如其名所隐含的,#undef指令取消(反定义)一个原来由#define指令创建的名称。
语法
#undef
标识符
#undef指令取消标识符的当前定义。其结果是,标识符的每次出现都将被预处理器所忽略。为取消一个用#undef的宏定义,只须给出宏的标识符,不须给出参数表。
你也可以将#undef指令用于一个原来未定义的标识符。这将确认这个标识符是未定义的。宏替换不能在#undef语句中执行。
#undef指令通常和一个#define指令匹配,以在源程序中创建一个区域,在这个区域中一个标识符有其特定的含义。例如,源程序的一个特有函数可以使用显式常量定义不影响程序余下部分的环境特定值。#undef指令也可与#if指令配对以控制源程序的条件编译过程。有关更多信息参见“#if、#elif、#else和#endif指令”。
下面的例子中,#undef指令取消了一个符号常量和一个宏的定义,注意该指令只给出了宏的标识符。
#define WIDTH 80
#define ADD(X,Y) (X)+(Y)
...#undef WIDTH
#undef ADD
Microsoft特殊处
宏可通过采用/U选项的命令行反定义,此命令行后跟反定义的宏名称。此命令与在文件开头处的#undef 宏名称语句序列的作用是相等的。
Microsoft特殊处结束
________________________________________
预处理器操作符
#define指令的文本中有四种预处理器特有的操作符(它们的总结参见下面的表)。
字符化、字符串化和语言符号粘贴操作符将在下面三章中讨论。defined操作符的信息参见“#if、#elif、#else和#endif指令”。
运算符 动作
字符串化操作符(#) 将相应实参置于双引号内
上一页 [1] [2] [3] [4] [5] [6] [7] [8] 下一页