瑾代表个人看法
如有问题请指出
<1>由来
在C++的历史发展中,有很多的语言特征(特别是语言的晦涩之处)来自于C语言,预处理就是其中的一个。C++从C语言那里把C语言预处理器继承过来(C语言预处理器,被Bjarne博士简称为Cpp,应该为C Program Preprocessor的简称)。
<2>预处理的定义
预处理指令是计算机的术语一种,是指提供按条件跳过源文件中的节、报告错误和警告条件,以及描绘源代码的不同区域的能力。
<3>常见的预处理指令
指令 说明
# 空指令,无任何效果
#include 包含一个源代码文件
#define 定义宏
#undef 取消已定义的宏
#if 如果给定条件为真,则编译下面代码
#ifdef 如果宏定义已经定义,则编译下面代码
#ifndef 如果宏没有定义,则编译下面代码
#elif 如果前面的#if给定条件不为真,当前条件为真,则编译下面代码
#endif 结束一个 #if…#else 条件编译块
#else #if指令的条件不 用于某个#if指令之后,当前面的为真时,就编译 #else后面的代码。#endif指令将终止上面的条件块。#elif预处理 指令综合了#else和#if指令的作用。
#error 发出错误
#warning 发出警告。
#region 和 #endregion,用于显式标记源代码中的节。
<4>指令注意事项
(注意: 1. 预处理指令总是占用源代码中的单独一行,并且总是以 # 字符和预处理指令名称开头。# 字符的前面以及 # 字符与指令名称之间可以出现空白符。
2. 包含 #define、#undef、#if、#elif、#else、#endif 或 #line 指令的源代码行可以用单行注释结束。在包含预处理指令的源行上不允许使用带分隔符的注释(/* */ 样式的注释)。
3. 预处理指令既不是标记,也不是 C# 句法文法的组成部分。但是,可以用预处理指令包含或排除标记序列,并且可以以这种方式影响 C# 程序的含义)
<5>使用规范
预处理指令的格式如下:
# define tokens
#符号应该是这一行的第一个非空字符,一般我们把它放在起始位置。如果指令一行放不下,可以通过反斜杠“/”进行控制,例如:
#define Error /
if(error) exit(1)
等价于
#define Error if(error) exit(1)
不过我们为了美化起见,一般都不怎么这么用,更常见的方式如下:
# ifdef __BORLANDC__
if_true<(is_convertible<value,named_template_param_base>::value)>::
template then<make_named_arg, make_key_value>::type Make;
# else
enum { is_named = is_named_parameter<value>::value };
typedef typename if_true<(is_named)>::template
then<make_named_arg, make_key_value>::type Make;
# endif
<6>部分淘汰使用方式
我们用<iostream>还是<iostream.h>?
我们主张使用第一种,而不是<iostream.h>
首先,.h格式的头文件早在98年9月份就被标准委员会抛弃了
其次,iostream.h只支持窄字符集,iostream则支持窄/宽字符集,扩大了使用范围
还有,标准对iostream作了很多的改动,接口和实现都有了变化,其相应使用规范发生改变
最后,iostream组件全部放入namespace std中,防止了名字污染,保证文件的稳定性
<7>常见疑惑
<io.h>和"io.h"的区别?
其实他们唯一的区别就是搜索路径不同:
对于#include <io.h> ,编译器从标准库路径开始搜索
对于#include “io.h” ,编译器从用户的工作路径开始搜索
本文参考文献《浅析C++里面的宏》一文
如有转载表明出处