预处理功能介绍 为有助于执行编译过程,经常可以使用一些预处理命令。每条预处理命令都具备一定的预处理功能。 常用的预处理命令有以下三项: 1.宏定义命令 2.文件包含命令 3.条件编译命令。 预处理命令具有以下特点: 1.在左边加 # 号,作为标志。 2.一般独占一行。 3.预处理命令不是编程语句,因此句末不加分号。 4.在正常编译过程之前作为预备动作而执行,编译过程结束后不占用存储空间。 宏定义命令
#define PI 3.14159 #define SIZE 80 宏定义命令被执行时,用字符串替代宏名,例如用3.14159替代PI,用80替代SIZE,等。 [例1]计算圆周长和面积。 #define PI 3.14159 void main( ) { double circum, area, r = 3; circum = 2 * PI * r; area = PI * r * r; } 宏定义命令被执行时,不作语法检查。例如,用户希望将EXEC宏替代整句语句(例如int i=5;),使用以下宏: #define EXEC int i=5 其中遗漏了分号(int i=5;才是完整语句),但因不作语法检查,因此查不出以上错误,而直到编译系统将其它使用该宏的语句进行编译时才能发现错误。
例如: #define ADD(x,y) x+y [例1]计算两数之和。 #include <iostream.h> #define ADD(x,y) x+y void main( ) { int a(40), b(50); //将a、b分别初始化为40、50 int sum = ADD(a, b); //宏替代结果为int sum = a + b; cout<<sum; } 运行结果: 90 宏替代的操作服从于运算符的优先级,见下例: [例2]计算数的平方。 // macro_3.cpp // Attention in defining macro // From Lv's book, p.85 #define SQ(x) x*x #include <iostream.h> void main() { int a = 2, b = 3; cout << SQ(a+b) << endl; //由于乘法运算符优先级高于加法运算符,所以执行a+b*a+b } /* Result: should be 25, but we get a+b*a+b=11 */ 问题出在优先级,应改正如下: // macro_1.cpp #define SQ(x) (x)*(x) #include <iostream.h> void main() { int a = 2, b = 3; cout << SQ(a+b) << endl; //即(a+b)*(a+b) } /* Result: 25 */ 请注意:宏不是函数(子程序)! 宏与函数的区别:宏节省时间但占用空间;函数节省空间但增加时间! 文件包含 如果以上所述的宏定义语句很多,则可将它们包含于一个单独的文件中,例如 "macros.h" 中。此macros.h文件内容例如可为: // macros.h #define MAX 32 #define sq(n) (n)*(n) #define PI 3.14159 … … 此时用户程序可简化为只包含以下一条语句: #include "macros.h" 即可执行以上所有宏命令。 以上macros.h称为头文件(header files)(或称包含文件,include files)。 其中系统所定义的头文件名称(例如iostream.h)使用尖括弧< >将头文件名称iostream.h包括起来,系统就根据这点到系统的文件夹中去调用;而用户自定义的头文件则用双引号" "将头文件名称包括起来,例如"macros.h"。系统就根据这点到用户程序的文件夹中去调用。请注意区别此点。 C++语言系统中有很多头文件,它们除包含宏替代定义语句外,更主要包含函数原型和类的定义或类的接口,及其所用各种数据类型的全局变量、外部静态变量和常量的定义。 条件编译 条件编译命令的功能是规定某些语句(或某个程序块)在一定条件下才参加编译,否则跳过不予理睬。 其主要用途为:防止遗漏定义或避免重复定义;以及在测试时增加某些测试语句,以实现调试跟踪的目的。本节主要讲防止遗漏定义或避免重复定义的功能。 其格式为: #ifdef (常量表达式)(或 #if defined(常量表达式)) [条件编译语句] #endif 或 #ifndef (常量表达式)(或 #if not defined(常量表达式)) [条件编译语句] #endif 以上语句中,当常量表达式无定义时,就编译两个条件编译命令#ifdef(或#ifndef)与#endif之间的条件编译语句。 条件编译命令也可表达如: #if (常量表达式) [条件编译语句] #endif 此时如常量表达式非零,则满足编译条件,编译两个条件编译命令#if与#endif之间的条件编译语句。 现在讲解其避免遗漏定义和避免重复定义的功能: 以下使用 #ifndef MAX,此即(# if not defined MAX)或(#if !defined MAX) 例题: // test_ifndef_1.cpp // To prevent the missing of macro definition #include <iostream.h> #ifndef MAX #define MAX 32 #endif void main() { cout << "MAX is " << MAX << endl; } /* Result: MAX is 32 */ 上例中MAX没有定义,所以执行条件编译语句#define MAX 32语句。 <例2>此例中MAX已经定义过了,故不执行条件编译语句 // test_ifndef_2.cpp // To prevent the missing of macro definition #include <iostream.h> #define MAX 10 #ifndef MAX #define MAX 32 #endif void main() { cout << "MAX is " << MAX << endl; } /* Result: MAX is 10 */ 上例中MAX已被定义为等于10,所以不执行条件编译语句#define MAX 32语句。再说,如果真是执行了条件编译语句#define MAX 32语句,必将会出现如下警告: warning: 'MAX' : macro redefinition test_ifndef_2.cpp(6) : see previous definition of 'MAX' 再看避免重复包含头文件的例子: [例3]防止重复包含头文件。 设已有头文件如下: // ifndef.h // To avoid the duplication of include files #if !defined(_IFNDEF_H) #define _IFNDEF_H int var=1; //global variable #endif //_IFNDEF_H 用户应用程序如下: // test_ifndef_3.cpp // To prevent the duplication of macro definition #include <iostream.h> #include "ifndef.h" #include "ifndef.h" //看似重复包含,实则不予执行 void main() { cout << "变量var = " << var << endl; } /* Result: 变量var = 1 */ 此程序中虽然多了一句#include "ifndef.h",但第二句不起作用。原因在于头文件中使用了条件编译功能。怎么知道重复包含的第二句不起作用?因为如果包含第二句的话,将会出错。如下: // test_ifndef_4.cpp // The error of the duplication of macro definition #include <iostream.h> int var=1; int var=1; void main() { cout << "变量var = " << var << endl; } /* Result : Not working error C2374: 'var' : redefinition; multiple initialization */ 在任何头文件中,都必须使用上述条件编译语句以便避免重复包含。在有些头文件中,也可能使用语句#pragma once,只要在头文件的初始部分加入这条指令,就能够保证头文件只被编译一次。有时同时使用条件编译语句#if !defined(_IFNDEF_H)和#pragma语句。 =============================================== 转载时请表明出处:http://www.cofftech.com/thread-5771-1-1.html |
<C++学习笔记>预处理功能
最新推荐文章于 2024-01-24 17:24:24 发布