//第二十五章补充内容 1 预处理过程
//1.1 预处理指令
/*
# 空指令,没有任何效果
#include 从该提令位置处包含一个源代码文件
#define 定义一个宏
#undef 取消已定义的宏
#ifdef 如果给定的宏已经定义,则编译下面的代码
#if 如果给定的条件成立,就编译下面的代码
#elif 如果前面#if给定的条件不成立,而当前给定的条件成立,那么编译下面的代码
#endif 结束一个#if...#else条件编译块
#error 停止编译并显示错误信息
*/
//1.2 #include 指令
//1.3 #define 指令
//#define Tow 2 该指令指示预处理程序在任何看到Two的地方都用2来替换,因此假如你写如下代码:
//1.4 用#define指令替换常量
//但由于#define指令仅仅进行两个字符串的替换,比如说在预处理时将Two替换为2,而不做类型检查,它不会像const那样定义一个具体类型,
//因此用关键字const比用#define要好很多
//1.5 用#define定义一个特定字符串并对其进行测试
/*#include <iostream>
using namespace std;
//#define Two
int main()
{
#ifdef Two
cout<<"宏Two已经定义"<<endl;
#else
cout<<"宏Tow未定义"<<endl;
#endif
return 0;
}*/
//ifndef 与#ifdef正好相反
/*#include <iostream>
using namespace std;
int main()
{
#ifndef Two
cout<<"Two宏未定义"<<endl;
#else
cout<<"Two宏已经定义"<<endl;
#endif
return 0;
}*/
// 1.6 #ifdef #define 和#endif的用途
// 1.7 带参数的#define
//#define也可以用于创建宏函数 #define func(x) ((x)*2)
/*#include <iostream>
using namespace std;
#define func(x) ((x)*2)
int main()
{
cout<<func(2)<<endl;
cout<<"执行完成";
return 0;
}*/
//宏函数允许有多个参数, #define max(x,y) ((x)>(y) ? (x): (y))
//想知道宏中为什么出现那么多的括号,接下来我们用一个程序来解释这个问
/*#include <iostream>
using namespace std;
#define func1(x) ((x)*2)
#define func2(x) x*2
int main()
{
int x, y;
x = func1(10);
cout<<"x:"<<x<<endl;
y = func2(10);
cout<<"y:"<<y<<endl;
x = func1(10+1);
cout<<"x:"<<x<<endl;
y = func2(10+1);
//func2(10+1)参数x在每次使用宏时都没有放在括号里,因此10初始化了x后,变成了10+1*2 算出结果为12,与前一个结果大相径
cout<<"y:"<<y<<endl;
return 0;
}*/
//1.8 宏与内联函数
/*#include <iostream>
using namespace std;
inline int func1(int x){ return (x)*2;}
inline int func2(int x){ return x*2; }
int main()
{
int x, y;
x = func1(10);
cout<<"x:"<<x<<endl;
y = func2(10);
cout<<"y:"<<y<<endl;
x = func1(10+1);
cout<<"x:"<<x<<endl;
y = func2(10+1);
cout<<"y:"<<y<<endl;
return 0;
}*/
//由于内联函数是将参数传递到函数体中进行计算的,而不是简单的替换,因此结果会与宏函数有所不同
//内联函数与宏的相同之处是两者都将函数的内容都放到调用函数的当前行中,这避免了调用函数的来回跳转,因此执行起来很快
//1.9 #运算符
//#运算符将位于其后的任何字符用引号引起来,
//#define show(x) cout<<#x;
/*#include <iostream>
using namespace std;
#define show(x) cout<<#x
int main()
{
show(hello word);
cout<<endl;
return 0;
}*/
// 1.10 ##运算符
//##运算符允许将多个单词连接为一个新的单词
//#define show(x) "Show" ## x ## "Student"
/*#include <iostream>
using namespace std;
#define show(x) "Show " ## x ## " Student"
int main()
{
cout<<show("xlc")<<endl;
cout<<endl;
return 0;
}*/
// 1.11 #undef 指令
//该指令的作用使已经定义的宏在以后的代码不起作
// 1.12 #if指令
// 1.13 #endif指令
// 1.14 #if defined 指令
//该指令检测的不是宏代表的值,而是宏是否被定义
/*#include <iostream>
using namespace std;
#define command
int main()
{
#if defined command
cout<<"command宏已经被定义"<<endl;
#endif
return 0;
}*/
// 1.15 #ifdef 和#ifndef指令
// 1.16 #elif指令
//#elif指令综合了#else和#if的作用
/*#include <iostream>
using namespace std;
#define Two
int main()
{
#ifdef Two
cout<<"Two已经定义"<<endl;
#elif defined Text
cout<<"Text已经定义"<<endl;
#elif defined One
cout<<"One已经定义"<<endl;
#else
cout<<"没有定义任何信息";
#endif
return 0;
}*/
// 1.17 #error指令
//#error指令使编译器显示一条错误信息,然后停止编译
/*#include <iostream>
using namespace std;
#define Test
int main()
{
#ifndef Test
#error
//Test未定义会导致编译失败
#endif
return 0;
cout<<"程序结束"<<endl;
}*/
// 1.18 #line指令
// 1.19 #pragma 指令
//格式Pragma Para
// 1 message参数
// #Pragma message("提示文本");
// 编译器遇到这条掻令时就在编译输出窗口中将消息文本打印出来
/*#include <iostream>
using namespace std;
#define _x86 500
int main()
{
#if _x86 == 500
#pragma message("处理器为奔腾500已经确定")
//这里的内容是输出在测试信息窗口的
#endif
return 0;
}*/
// 2 code_seg参数
// 3 #pragma once
//#pragma once 是个比较常用的指令,只要在头文件的最开始加入这条指令就能够保证头文件只被编译一次,假设我们有3个头文件,one.h two.h three.h
/*#include "three.h"
int main()
{
//这里是因为father类重定义了,
grandson a;
a.show();
return 0;
}*/
//这条指讼实际上在VC6.0中就已经有了,但是考虑到兼容性,并没有太多的使用它
// 4 不常用的#pragma 指令
// (1) #pragma hdtstop
// (2) #pragma resource "*.dfm"
// (3) #pragma warning