c++ 中 预编译指令

#include 包含头文件
#if 条件
#else 否则
#elif 否则如果
#endif 结束条件
#ifdef 或 #if defined 如果定义了一个符号, 就执行操作
#ifndef 或 #if !defined 如果没有定义一个符号,就指执行操作
#define 定义一个符号
#undef 删除一个符号
#line 重新定义当前行号和文件名
#error 输出编译错误 消息, 停止编译
#pragma 提供 机器专用的特性,同时保证与C++的完全兼容

include:
include 用“”来包含自定义头文件,从用户的工作路径开始搜索,用<>来包含标准库头文件,从标准库路径开始搜索.
对于<iostream>和<iostream.h>,虽然两者都能实现,但是,对于标准库的头文件,推荐不加.h,这是标准.
只能include 头文件

编译控制指令:
控制代码的编译过程,防止重定义.,以及版本控制等功能.

#define 宏定义符号
#define DDD “12415afafwa”
#define EEE 12333344
#define CCC
DDD定义字符串,是char*类型,EEE是int类型,  CCC只声明符号,但为赋值,一般只用与检测防止重定义,在c++中定义常量一般使用const,而不是define宏
define除了宏定义符号外,还可以定义函数操作
#define MAX(a,b) (a>b)?(a):(b)
#define PLUS(x,y)\
{\
cout<<x+y<<endl;\
}
多行函数每行末尾加一个\,最后一行不加。
define中的使用宏 ##、#@、#。##就是连接的意思,#@是两边加单引号,#就是双引号了,例
#define A(x) A_##x
#define B(x) #@x
#define C(x) #x
int A(1)=2;
char d=B(.);
char *bbq=C(asfasgw);
使用define执行函数操作的优点:
使用函数需要额外的开销,它需要开辟栈空间,记录返回地址,将形参压栈,从函数中返回,释放堆栈,而define中的形参却不占用内存,即节约空间,也节约时间。
对于上述的MAX(x,y)宏,它可以进行int,float,double,等其他可用>比较大小的数据类型的大小判断,而函数的形参要与实参一致。
缺点:
每次使用就是将宏拷贝入程序中,大量使用会大幅度增加程序的长度。



#undef
删除#define定义的符号
#define PI 132
#undef PI

#if #else  #elif  #endif 
#ifdef  == #if defined 
#ifndef ==  #if !defined 
判断语句,进行各种判断来保证编译的顺利进行
用if开始判断,最后一定要用#endif来结束
#if  !defined AAA
defined AAA
#endif
懒得写,摘点百度百科:
#if defined block1 && defined block2
...
#endif
#if CPU==PENTIUM4
...
#endif
#if LANGUAGE == ENGLISH
#define Greeting "Good Morning."
#elif LANGUAGE == GERMAN
#define Greeting "Guten Tag."
#elif LANGUAGE == FRENCH
#define Greeting "Bonjour."
#else
#define Greeting "Hi."
#endif
std::cout<<Greeting << std::endl;
#if VERSION == 3
...
#elif VERSION == 4
...
#else
...
#endif
可以看见,我们使用这些判断语句,可以对系统进行判断,对版本进行判断,从而确保不同系统上的不同版本的程序都能正确的运行。也可以避免重复引用同一个头文件或其他情况的重定义。


标准的预处理器宏:
__LINE__ 当前 源文件中的代码行号,十进制整数
__FILE__   源文件的名称,字符串 字面量
__DATE__  源文件的处理日期,字符串 字面量,格式mmm dd yyyy其中mmm是月份如Jan、Feb等 dd是01-31 yyyy是四位的年份
__TIME__ 源文件的编译 时间,也是字符串 字面量格式是hh:mm:ss
__STDC__ 这取决于实现方式,如果 编译器选项设置为编译标准的C代码,通常就定义它,否则就不定义它
__cplusplus 在编译C++ 程序时,它就定义为199711L
   
#line
可以修改__FILE__返回的字符串
cout<<__FILE__<<__LINE__<<endl;
#line 158
cout<<__FILE__<<__LINE__<<endl;
#line __LINE__"ffffff"
cout<<__FILE__<<__LINE__<<endl;
#line 200"fff"
cout<<__FILE__<<__LINE__<<endl;



#error
在预处理阶段,如果出现了错误,则#error指令可以生成一个诊断 消息,并显示为一个编译错误,同时中止编译

#pragma
专门用于实现预先定义好的选项,其结果在编译器说明文档中进行了详细的解释。编译器未识别出来的#pragma指令都会被忽略
对于我所使用的vs2012中,有一个常用的预编译指令
#pragma once
确保头文件只被编译一次
如果不用这个的话,要使头文件不重复编译的写法为将整个头文件的内容全部写在判断内部
//#pragma once
#ifndef A_H
#define A_H
#include "stdafx.h"
const static int bb=0;//
extern int cc=0;
static int dd=5;
int ee;
#endif

#assert()宏
在标准库头文件<cassert>中声明
用于在 程序中 测试一个 逻辑表达式,如果逻辑表达式为false, 则assert()会终止 程序,并显示诊断 消息
用于在条件不满足就会出现重大错误,所以应确保后面的语句不应再继续执行,所以它的应用非常灵活
注意: assert不是错误处理 机制, 逻辑表达式的结果不应产生负面效果,也不应超出 程序员的控制(如找开一个文件是否成功), 程序应提供适当的代码来处理这种情况
可以使用#define NDEBUG来关闭断言 机制
int a=5;
int c=3;
assert(c<a);


assert(a<c);

#define NDEBUG必须放在#include <cassert>前,才能关闭断言


你可能感兴趣的:(c++ 中 预编译指令)