编程技术是改变世界的力量。
本站
当前位置:网站首页 > 后端语言 > 正文

C/C++ 编译预处理及条件编译(c++的编译预处理包括哪三种情况)

gowuye 2024-04-25 04:46 12 浏览 0 评论

#C/C++#

在编译器对源程序进行编译之前,首先要由预处理器对程序文本进行预处理。预处理提供了一组编译预处理指令和预处理操作符。预处理指令实际上不是 C++ 语言的一部分,它只是用来扩充 C++ 程序设计的环境。所有的预处理指令在程序中都是以 “#”来引导,每一条预处理指令单独占用一行,不要用分号结束。预处理指令可以根据需要出现在程序的任何位置。

1、#include 指令

#include 指令也称为文件包含指令,其作用是将另一个源文件嵌入到当前源文件该点处。通常用 #include 指令来嵌入头文件。文件包含指令有如下两种格式。

  1. #include <文件名>
    按标准方式搜索,文件位于系统目录下的 include 子目录下。
  2. #include “文件名”
    首先在当前目录中搜索,若没有,再按标准方式搜索。
    #include 指令可以嵌套使用。假设有一个头文件 myhead.h ,该头文件中又可以有如下的文件包含指令:
    #include "file1.h"
    #include "file2.h"

2、#define 和 #undef 指令

预处理器最初是为C语言设计的,#define 曾经在 C 程序中被广泛使用。但 #define 能完成的一些功能,能够被C++引入的一些语言特性很好的替代。在C语言中,用 #define 来定义符号常量,例如下面的预编译指令定义了一个符号常量 PI 的值为 3.14:#define PI 3.14在C++中虽然仍然可以这样定义符号常量,但是更好的方法是在类型说明语句中用 const 进行修饰。在C语言中,还可以用 #define 来定义带参数宏,以实现简单的函数计算,提高程序的运行效率,但是在C++中这一功能已经被内联函数取代。用 #define 还可以定义空符号,例如:#define MYHEAD_H定义它的目的,仅仅是表示“MYHEAD_H 已经定义过”这样一种状态。将该符号配合条件编译指令一起使用,可以起到一些特殊作用,这是C++程序中 #define 的最常用之处。#undef 的作用是删除由 #define 定义的宏,使之不再起作用。

3、条件编译指令

使用条件编译指令,可以限定程序中的某些内容要在满足一定条件的情况下参与编译。因此,利用条件编译可以使用一个源程序在不同的编译条件下产生不同的目标代码。例如,可以在调试程序时增加一些调试语句,以达到跟踪的目的,并利用条件编译指令,限定当程序调试好后,重新编译时,使调试语句不参与编译。常用的编译语句有下列 5 种形式。

  • 形式一
#if 常量表达式
        程序段         // 当“常量表达式”非零时编译本程序段
#endif
  • 形式二
#if 常量表达式
        程序段 1        // 当“常量表达式”非零时编译本程序段
#else 
        程序段 2        // 当“常量表达式”为零时编译本程序段
#endif
  • 形式三
#if 常量表达式 1
        程序段 1       // 当“常量表达式 1”非零时编译本程序段
#elif 常量表达式 2
        程序段 2       // 当“常量表达式 1”为零、“常量表达式 2” 非零时编译本程序段时编译本程序段
        .
        .
        .
#elif 常量表达式 n
        程序段 n       // 当“常量表达式 1”、···“常量表达式 n-1” 均为零、"常量表达式 n"非零时编译本程序段
#else
        程序段 n + 1 // 其它情况下编译本程序段
#endif
  • 形式四
#ifdef 标识符
        程序段 1
#else
        程序段 2
#endif

如果“标识符”经 #define 定义过,且未经 undef 删除,则编译程序段 1,否则编译程序段 2.如果没有程序段 2,则 #else 可以省略。

  • 形式五
#ifndef 标识符
        程序段 1
#else
        程序段 2
#endif

如果“标识符”未被定义过,则编译程序段 1,否则编译程序段 2。如果没有程序段 2,则 #else 可以省略。

4、defined 操作符

defined 是一个预处理操作符,而不是指令,因此不能以 # 开头。defined 操作符使用的形式为:defined (标识符)若“标识符”在此前经 #define 定义过,并且未经 #undef 删除,则上述表达式为非零,否则上述表达式的值为零。下面两种写法完全等效的。

#ifndef MYHEAD_H
#define NYHEAD_H
        ···
#endif     

等价于

#if ! defined(MYHEAD_H)
#define MYHEAD_H
        ···
#endif        

由于文件包含指令可以嵌套使用,在设计程序时要避免多次重复包含同一个头文件,否则会引起变量及类的重复定义。例如,某个工程包括如下 4 个源文件。

// main.cpp
#include "file1.h"
#include "file2.h"

int main()
{
    ···
}

// file1.h
#include "head.h"
    ···
    
// file2.h
#include "head.h"
    ···
    
// head.h
    ···
class Point
{
    ···
}
    ···

这时,由于 #include 指令的嵌套使用,使得头文件 head.h 被包含了两次,于是编译时系统会指出错误:类 Point 被重复定义。如何避免这种情况呢?这就要在可能被重复包含的头文件使用条件编译指令。用一个唯一的标识符来标记某文件是否已经参加过编译,如果已经参加过编译则说明该程序段是被重复包含的,编译时忽略重复部分。将文件 head.h 改写如下:

// head.h
#ifndef HEAD_H
#define HEAD_H
    ···
class Point
{
    ···
}
    ···
#endif

在这个头文件中,首先判断标识符 HEAD_H 是否被定义过。若未定义过,说明此头文件尚未参加过编译,于是编译下面的程序段,并且对标识符 HEAD_H 进行宏定义,标记此文件已参加过编译。若标识符 HEAD_H 被定义过,说明此头文件参加过编译,于是忽略下面的程序段。这样便不会造成对类 Point 的重复定义。

相关推荐

R语言数据挖掘实践——支持向量机的常用函数
R语言数据挖掘实践——支持向量机的常用函数

e1071包是R语言中用于支持向量机建模与分析的软件包,其主要用于支持向量机的模型构建,提供核心函数svm()来建立支持向量机的基础模型,并且可辅助使用pred...

2024-05-18 12:15 gowuye

R数据分析:如何做聚类分析,实操解析
R数据分析:如何做聚类分析,实操解析

Clusteringisabroadsetoftechniquesforfindingsubgroupsofobservationswi...

2024-05-18 12:14 gowuye

用R语言做数据分析——马赛克图
用R语言做数据分析——马赛克图

到目前为止,我们已经学习了许多可视化定量或连续型变量间关系的方法。但如果变量是类别型的呢?若只观察单个类别型变量,可以使用柱状图或者饼图;若存在两个类别型变量,...

2024-05-18 12:14 gowuye

用R语言做数据分析——方差分析基本概论
用R语言做数据分析——方差分析基本概论

在实际工作中,影响一件事的因素是很多的,我们总是希望通过各种试验来观察各种因素对试验结果的影响。例如,不同的生产厂家、不同的原材料、不同的操作规程,以及不同的技...

2024-05-18 12:14 gowuye

R语言数据分析实战:数据清洗与可视化
R语言数据分析实战:数据清洗与可视化

《R语言数据分析实战:数据清洗与可视化》是一本深入浅出的实践指南,专为对数据分析感兴趣的读者精心编撰。本书旨在帮助读者掌握R语言这一强大的统计分析工具,通过实例...

2024-05-18 12:13 gowuye

用R语言做数据分析——双因素方差分析
用R语言做数据分析——双因素方差分析

在双因素方差分析中,受试者被分配到两因子的交叉类别组中。以基础安装中的Tooth-Growth数据集为例,随机分配60只豚鼠,分别采用两种喂食方法(橙汁或维生素...

2024-05-18 12:13 gowuye

用R语言做数据分析——独立两样本和K样本检验
用R语言做数据分析——独立两样本和K样本检验

coin包简介对于独立性问题,coin包提供了一个进行置换检验的一般性框架,通过这个包,我们可以回答如下问题:响应值与组的分配独立吗?两个数值变量独立吗?两个类...

2024-05-18 12:13 gowuye

用R语言做数据分析——用回归做方差分析
用R语言做数据分析——用回归做方差分析

之前提到方差分析和回归都是广义线性模型的特例,之前文章的所有设计都可以用lm()函数来分析。为了更好地理解输出结果,需要弄明白在拟合模型时,R语言是如何处理类别...

2024-05-18 12:13 gowuye

数据分析R语言——数据结构
数据分析R语言——数据结构

数据分析R语言——数据结构数组数组(array)与矩阵类似,但是维度可以大于2.数组通过array()函数创建。形式如;myarray<-array(v...

2024-05-18 12:13 gowuye

R语言数据挖掘实践——关联分析的常用函数
R语言数据挖掘实践——关联分析的常用函数

arules和arulesViz是R语言中两个专用于关联分析的软件包。其中arules用于关联规则的数字化生成,提供Apriori和Eclat这两种快速挖掘频繁...

2024-05-18 12:12 gowuye

R语言数据挖掘实践——判别分析的常用函数
R语言数据挖掘实践——判别分析的常用函数

判别算法在R语言中实现主要涉及4个软件包中的相关函数,它们依次为MASS、klaR、class和kknn。其中MASS包含有大量实用而先进的统计计数函数及适用数...

2024-05-18 12:12 gowuye

用R语言读取Excel、PDF和JSON文件,终于有人讲明白了
用R语言读取Excel、PDF和JSON文件,终于有人讲明白了

导读:本文将讨论Excel、PDF等文件的读取,以及相应函数的参数设置。作者:刘健邬书豪如需转载请联系华章科技下图总结了主要程序包,希望读者在日常练习和工作中...

2024-05-18 12:12 gowuye

R语言数据挖掘实践——聚类分析的常用函数
R语言数据挖掘实践——聚类分析的常用函数

使用R语言可以轻松实现聚类分析,stats、cluster、fpc和mclust是常用的四个聚类分析软件包。stats主要包含一些基本的统计函数,如用于统计计算...

2024-05-18 12:12 gowuye

用R语言做数据分析——时间序列分类
用R语言做数据分析——时间序列分类

时间序列分类是根据已标注的时间序列建立一个分类模型,然后使用分类模型预测未标记时间序列的类别。从时间序列中抽取出新特征肯呢个有助于提高分类模型的性能。特征提取技...

2024-05-18 12:11 gowuye

一文看懂用R语言读取Excel、PDF和JSON文件(附代码)
一文看懂用R语言读取Excel、PDF和JSON文件(附代码)

导读:本文将讨论Excel、PDF等文件的读取,以及相应函数的参数设置。作者:刘健邬书豪如需转载请联系华章科技下图总结了主要程序包,希望读者在日常练习和工作中...

2024-05-18 12:11 gowuye

取消回复欢迎 发表评论: