预处理命令总结

C++预处理命令有三种:宏定义命令、文件包含命令、条件编译命令。这些命令在程序中都是以“#”来引导的,每条预处理指令必须单独占用一行,但在行尾不允许有分号“;”。

1.宏定义命令

使用#define定义

1).常量定义

#define PI 3.1415926

这里的#define就是宏定义命令,编译器在处理这个代码之前会对PI进行处理替换为3.1415926,PI称为宏名。
通常宏名定义为大写,以便与普通标识符区别。
宏被定义后,通常不允许再重新定义,只有使用 #undef 命令才可以重新定义。
一个定义过的宏可以用于定义其他新的宏。
这样的定义看起来类似于普通的常量定义CONST,但也有着不同,因为#define的定义更像是简单的文本替换,而不是作为一个量来使用。

2).带参数定义

#define MIN(A,B)((A)<=(B)?(A):(B))//两个参数返回较小的一个

其中,(A,B)是宏MIN的参数表

3).单行定义

#define HDY_HR_JSON "HDY_HR.json"

4).多行定义

#define CHECK_CANCEL_AND_QUIT() if (类名::函数名())\
    return;

2.文件包含定义

文件包含定义是指将另一个源文件的内容合并到源程序中。C++语言提供了#include命令用于实现文件包含的操作,它有两种格式:

#include <xxx.h>
#include "xxx.h"

文件名通常以“.h”为扩展名,将其称为“头文件”。
#include <xxx.h>与#include "xxx.h"有什么区别?
第一种编译器从标准库路径开始搜索xxx.h。
第二种编译器从用户工作路径开始搜索xxx.h。

3.条件编译命令

一般情况下,源程序中所有的语句都参加编译,但有时也希望根据一定条件去编译源文件的不同部分,即“条件编译”。条件编译使得同一源程序在不同条件下得到不同的目标代码。

格式1:

#ifdef <标识符>
    <程序段1>
[
#else
    <程序段2>
]
#endif

其中,#ifdef、#else、#endif都是关键字,<程序段>是由若干条预处理命令或语句组成。这种形式的含义是,如果标识符已被#define命令定义过,则编译<程序段1>,否则编译<程序段2>。

格式2:

#ifndef <标识符>
    <程序段1>
[
#else
    <程序段2>
]
#endif

与格式1的区别是,如果标识符没有被#define命令定义过,则编译<程序段1>,否则编译<程序段2>。

格式3:

#if <表达式1>
    <程序段1>
[
#elif <表达式2>
    <程序段2>
    ...
]
[
#else
    <程序段n>
]
#endif

其中,#if、#elif、#else、#endif为关键字。含义是,如果<表达式1>为“true”,编译<程序段1>;否则如果<表达式2>为“true”,编译<程序段2>,…;如果表达式都不为“true”,编译<程序段n>。

扩展:防止头文件被重复引用

第一种:

  #ifndef _NAME_H
  #define _NAME_H
  //头文件内容
  #endif

其中,_NAME_H 是宏的名称。需要注意的是,这里设置的宏名必须是独一无二的,不要和项目中其他宏的名称相同。
当程序中第一次 #include 该文件时,由于 _NAME_H 尚未定义,所以会定义 _NAME_H 并执行“头文件内容”部分的代码;
当发生多次 #include 时,因为前面已经定义了 _NAME_H,所以不会再重复执行“头文件内容”部分的代码。

第二种:

#pragma once

将其附加到指定文件的最开头位置,则该文件就只会被 #include 一次。
我们知道,#ifndef 是通过定义独一无二的宏来避免重复引入的,这意味着每次引入头文件都要进行识别,所以效率不高。
但考虑到 C 和 C++ 都支持宏定义,所以项目中使用 #ifndef 规避可能出现的“头文件重复引入”问题,不会影响项目的可移植性。
和 ifndef 相比,#pragma once 不涉及宏定义,当编译器遇到它时就会立刻知道当前文件只引入一次,所以效率很高。
但值得一提的是,并不是每个版本的编译器都能识别 #pragma once 指令,一些较老版本的编译器就不支持该指令(执行时会发出警告,但编译会继续进行),即 #pragma once 指令的兼容性不是很好。
目前,几乎所有常见的编译器都支持 #pragma once 指令,甚至于 Visual Studio 2017 新建头文件时就会自带该指令。可以这么说,在 C/C++ 中,#pragma once 是一个非标准但却逐渐被很多编译器支持的指令。
除此之外,#pragma once 只能作用于某个具体的文件,而无法向 #ifndef 那样仅作用于指定的一段代码。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值