Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1614942
  • 博文数量: 268
  • 博客积分: 8708
  • 博客等级: 中将
  • 技术积分: 3764
  • 用 户 组: 普通用户
  • 注册时间: 2007-04-06 15:58
文章分类

全部博文(268)

文章存档

2014年(1)

2013年(15)

2012年(23)

2011年(60)

2010年(51)

2009年(12)

2008年(59)

2007年(47)

分类: C/C++

2010-04-12 16:01:08


C++预处理指令

#include

#define 

#undef 

#pragma 

#import 

#error 

#line 

#ifdef 

#ifndef 

#if 

#else 

#elif 

#endif 



宏以#起始 不以;结束 



一.        #include 文件包含 

预编译期发现#include后,将会寻找HeaderName并把其包含到当前文件中 

EG:#include  

常见形式: 

#include           // 

#include             // 

#include "iostream"            // 

#include "TestHeader.h"        // 

#include "..\TestHeader.h"     // 



1.      #include 和#include 区别 

#include 是老规范,现已经抛弃 

#include 是新规范,使用名称空间避免名称冲突。即将所有的定义放在了一个名称空间std中 



2.      #include 和#include "iostream"区别 

#include 直接在系统的路径下查找此头文件。多是系统的头文件 

#include "iostream"首先在当前目录查找,如果没有找到再到系统目录查找 



3.      头文件的多次包含问题 

编译器对每个文件只编译一次生成一份机器代码.obj,如果在多个地方包含了同一个头文件,则会出现多次包含的错误,即试图让编译器将此文件编译多次生成多份机器代码。 

预编译保护解决此问题。 



二.        #define  #undef 宏替换 

#define 宏 宏主体 

宏展开:在代码中出现宏,会用宏实体代替宏 



#define 定义常量、函数宏 

#undef  结束常量、函数宏定义 



1.    常量宏 

常量宏:是最常见的一种形式。即使用一个宏代替实际的常量,如数据、字符、字符串常量等 

#define CONST_VAL 2 

#define MEG_EG "Test Macro!" 

#define CHARACTOR_EG 'M' 



注: 

(1)    可以使用#undef结束常量宏定义,结束宏定义宏此宏不能再次使用。即时这个宏实际不存在,使用#undef结束宏定义也不是错误,相反在定义一个宏时如果不确定其是否已经定义可以先使用#undef结束其定义,然后重新定义 

(2)    可以多次定义同一个宏 



2.    函数宏 

函数宏:外形和作用都与函数类似并且有参数输入 

#define MAX(x, y) ( (x>y)?x:y ) 



注: 

(1)    定义函数宏是将宏体都用一个“( ) “括起来。 

#define MAX(x, y) ( (x>y)?x:y ) 

cout << "MAX = " << MAX(1,2) << endl;  //正确 



#define MAX(x, y) (x>y)?x:y 

cout << "MAX = " << MAX(1,2) << endl;  //错误。将<<和宏混淆 

(2)    通常将函数宏第一为一行,但可以使用“\“定义多行宏函数 

           #define MAX(x, y) ( (x>y)?\ 

                       x:y ) 

(3)    可以使用#undef结束函数宏定义 

    #undef MAX(x, y)和#undef MAX都可以 

(4)    宏函数产生内联代码,形式上等同与inline函数,当没有inline函数安全 

(5)    宏函数不检查输入的参数(相比inline函数不安全) 

(6)    宏函数没有inline函数效率高 

   

3.    #运算符 

#运算符可以在一个字符串中输入宏参数,使得一个字符串可以包含某个参数 

EG: 

#define STR_A(A) ( printf("STR_A(A) A = "#A" ") ) 

#define STR_B(B) ( "STR_B(B) B = "#B" " ) 

#define STR_C(CA, CB) ( "STR_C(CA, CB) C = "#CA"  "#CB" " ) 

        STR_A(1); 

        cout << endl; 

        cout << STR_B(2) << endl; 

        cout << STR_B(B) << endl; 

        cout << STR_C(CA, CB) << endl; 

        

        string strB = "strB "; 

        strB += " + "; 

        strB += STR_B(B); 

cout << "strB + Macro STR_B = " << strB << endl; 

   

4.    ##运算符 

  ##运算符用于创建变化的变量,即使用宏参数创建变化的变量 

   

EG: 

       #define VARIAVLE_NAME(N) ( n##N ) 

        int VARIAVLE_NAME(IntA) = 1;                // int nIntA 

        int VARIAVLE_NAME(1) = 1;                   // int n1 

        int VARIAVLE_NAME(2) = 1;                   // int n2 

        cout << "nIntA = " << nIntA << endl; 

        cout << "n" << 1 <<" = " << VARIAVLE_NAME(1) << endl; 

        cout << "n" << 2 <<" = " << VARIAVLE_NAME(2) << endl; 

        

        double VARIAVLE_NAME(DoubleA) = 1.1; 

        cout << "nDoubleA = " << nDoubleA << endl; 

       

三.        #pragma 

其格式一般为: #pragma para 

其中para 为参数,下面来看一些常用的参数。 

(1)   #pragma once 

多次包含的保护。只要在头文件的最开始加入这条指令就能够保证头文件被编译一次,这条指令实际上在VC6中就已经有了,但是考虑到兼容性并没有太多的使用它。 



等价于:(此为C/C++标准 通用性更强) 

#ifndef HEADER_NAME_HPP 

#define HEADER_NAME_HPP 

             Your Code 

#endif //END HEADER_NAME_HPP 



(2)   #pragma warning() 

#pragma warning( warning-specifier : warning-number-list 

[; warning-specifier : warning-number-list...] ) 

#pragma warning( push[ ,n ] ) 

#pragma warning( pop ) 

       

       EG: 

       #pragma warning( disable : 4507 34; once : 4385; error : 164 ) 

等价于: 

#pragma warning(disable:4507 34) // 不显示和号警告信息 

#pragma warning(once:4385)       // 4385号警告信息仅报告一次 

#pragma warning(error:164)       // 把号警告信息作为一个错误。 



同时这个pragma warning 也支持如下格式: 

#pragma warning( push [ ,n ] ) 

#pragma warning( pop ) 

这里n代表一个警告等级(1---4)。 

#pragma warning( push )保存所有警告信息的现有的警告状态。 

#pragma warning( push, n)保存所有警告信息的现有的警告状态,并且把全局警告 

等级设定为n。 

#pragma warning( pop )向栈中弹出最后一个警告信息,在入栈和出栈之间所作的 

一切改动取消。例如: 

#pragma warning( push ) 

#pragma warning( disable : 4705 ) 

#pragma warning( disable : 4706 ) 

#pragma warning( disable : 4707 ) 

//....... 

#pragma warning( pop ) 

在这段代码的最后,重新保存所有的警告信息(包括,和)。 

(3)   #pragma warning() 

#pragma warning( warning-specifier : warning-number-list 

[; warning-specifier : warning-number-list...] ) 

#pragma warning( push[ ,n ] ) 

#pragma warning( pop ) 

       

       EG: 

       #pragma warning( disable : 4507 34; once : 4385; error : 164 ) 

等价于: 

#pragma warning(disable:4507 34) // 不显示和号警告信息 

#pragma warning(once:4385)       // 4385号警告信息仅报告一次 

#pragma warning(error:164)       // 把号警告信息作为一个错误。 



同时这个pragma warning 也支持如下格式: 

#pragma warning( push [ ,n ] ) 

#pragma warning( pop ) 

这里n代表一个警告等级(1---4)。 

#pragma warning( push )保存所有警告信息的现有的警告状态。 

#pragma warning( push, n)保存所有警告信息的现有的警告状态,并且把全局警告 

等级设定为n。 

#pragma warning( pop )向栈中弹出最后一个警告信息,在入栈和出栈之间所作的 

一切改动取消。例如: 

#pragma warning( push ) 

#pragma warning( disable : 4705 ) 

#pragma warning( disable : 4706 ) 

#pragma warning( disable : 4707 ) 

//....... 

#pragma warning( pop ) 

在这段代码的最后,重新保存所有的警告信息(包括,和)。 

四.        #import 

常用于导入.dll 



五.        #error 

    该指令用于程序的调试, 当编译中遇到#error指令就停止编译。 

     #if !defined(__cplusplus) 

#error C++ compiler required. 

#endif 

如果没有在__cplusplus环境下,就会输出This software requires the cplusplus OS.然后诱发编译器终止。所以总的来说,这条指令的目的就是在程序崩溃之前能够给出一定的信息。 

六.        #line 

用于重置__FILE__和__LINE__ 

初看起来似乎没有什么用,不过,他还是有点用的,那就是用在编译器的编写中,我们知道编译器对C++源码编译过程中会产生一些中间文件,通过这条指令,可以保证文件名是固定的,不会被这些中间文件代替,有利于进行分析 
阅读(866) | 评论(0) | 转发(0) |
0

上一篇:从UNIX到WINDOWS NT移植C++

下一篇:unix头文件

给主人留下些什么吧!~~