第二章补充C/C++预处理命令 预处理器是在程序源文件被编译之前根据预处理指令对程序源文件进行处理的程序。预处理器指令以#号开头标识,末尾不包含分号。预处理命令不是C/C++语言本身的组成部分,不能直接对它们进行编译和链接。C/C++语言的一个重要功能是可以使用预处理指令和具有预处理的功能。C/C++提供的预处理功能主要有文件包含、宏替换、条件编译等。 1文件包含 预处理指令#include用于包含头文件,有两种形式:#include <xxx.h>,#include "xxx.h"。尖括号形式表示被包含的文件在系统目录中。如果被包含的文件不一定在系统目录中,应该用双引号形式。在双引号形式中可以指出文件路径和文件名。如果在双引号中没有给出绝对路径,则默认为用户当前目录中的文件,此时系统首先在用户当前目录中寻找要包含的文件,若找不到再在系统目录中查找。对于用户自己编写的头文件,宜用双引号形式。对于系统提供的头文件,既可以用尖括号形式,也可以用双引号形式,都能找到被包含的文件,但显然用尖括号形式更直截了当,效率更高。 2宏替换 宏定义 宏定义的作用一般是用一个短的名字代表一个长的代码序列。宏定义包括无参数宏定义和带参数宏定义两类。宏名和宏参数所代表的代码序列可以是任何意义的内容,如类型、常量、变量、操作符、表达式、语句、函数、代码块等。但要尤其注意的是宏名和宏参数必须是合法的标识符,其所代表的内容及意义在宏展开前后必须一直是独立且保持不变的,不能分开解释和执行。 如果希望宏定义代码序列中标识符内出现的宏形参名能够被替换,可以在宏形参名与标识符之间添加连接符##,在宏替换过程中宏形参名和连接符##一起将被替换为宏实参名。##用于把宏参数名与宏定义代码序列中的标识符连接在一起,形成一个新的标识符。例如: #define BLOG(name) my_##name,BLOG(vrmozart)表示my_vrmozart #define BLOG(name) name##_ blog,BLOG(vrmozart)表示vrmozart_ blog #define BLOG(name) my_##name##_blog,BLOG(vrmozart)表示my_vrmozart_ blog 如果希望宏定义代码序列中的宏形参名被替换为宏实参名的字符串形式(即在宏实参名两端加双引号"),而不是替换为宏实参名,可以在宏定义代码序列中的宏形参名前面添加符号#。#用于把宏参数名变为一个字符串形式。例如: #define STR(name) #vrmozart,STR(vrmozart)表示"vrmozart" __DATE__,字符串常量类型,表示当前所在源文件的编译日期,输出格式为Mmmddyyyy(如May 27 2006)。 __TIME__,字符串常量类型,表示当前所在源文件的编译日期,输出格式为hh:mm:ss(如09:11:10)。 __FILE__,字符串常量类型,表示当前所在源文件名,且包含文件路径。 __LINE__,整数常量类型,表示当前所在源文件中的行号。 __FUNCTION__,字符串常量类型,表示当前所在函数名。 3条件编译指令 一般情况下,在进行编译时对源程序中的每一行都要编译,但是有时希望程序中某一部分内容只在满足一定条件时才进行编译,如果不满足这个条件,就不编译这部分内容,这就是条件编译。条件编译主要是进行编译时进行有选择的挑选,注释掉一些指定的代码,以达到多个版本控制、防止对文件重复包含的功能。#if,#ifndef,#ifdef,#else,#elif,#endif是比较常见条件编译预处理指令,可根据表达式的值或某个特定宏是否被定义来确定编译条件。 4其它预处理指令 除了上面讨论的常用预处理指令外,还有三个不太常见的预处理指令:#line、#error、#pragma,下面分别介绍。 ① #line #line指令用于重新设定当前由__FILE__和__LINE__宏指定的源文件名字和行号。 #line一般形式为#line number "filename",其中行号number为任何正整数,文件名filename可选。#line主要用于调试及其它特殊应用,注意在#line后面指定的行号数字是表示从下一行开始的行号。 ② #error #error指令使预处理器发出一条错误消息,然后停止执行预处理。 #error 一般形式为#error info,如#error MFC requires C++ compilation。 ③ #pragma #pragma指令可能是最复杂的预处理指令,它的作用是设定编译器的状态或指示编译器完成一些特定的动作。 #pragma一般形式为#pragma para,其中para为参数,下面介绍一些常用的参数。 #pragma once,只要在头文件的最开始加入这条指令就能够保证头文件被编译一次。 #pragma message("info"),在编译信息输出窗口中输出相应的信息,例如#pragma message("Hello")。 #pragma warning,设置编译器处理编译警告信息的方式,例如#pragma warning(disable:4507 34;once : 4385;error:164)等价于#pragma warning(disable:4507 34)(不显示4507和34号警告信息)、#pragma warning(once:4385)(4385号警告信息仅报告一次)、#pragma warning(error:164)(把164号警告信息作为一个错误)。 #pragma comment(…),设置一个注释记录到对象文件或者可执行文件中。常用lib注释类型,用来将一个库文件链接到目标文件中,一般形式为#pragma comment(lib,"*.lib"),其作用与在项目属性链接器“附加依赖项”中输入库文件的效果相同。 转自http://www.cnblogs.com/lidabo/archive/2012/08/27/2658909.html |
|
来自: dongtongtong > 《C Primer(第五版)》