预处理指令讲解

瑾代表个人看法

如有问题请指出

<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++里面的宏》一文

如有转载表明出处

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值