【C++知识点】预处理命令

✍个人博客:https://blog.csdn.net/Newin2020?spm=1011.2415.3001.5343
📚专栏地址:C/C++知识点
📣专栏定位:整理一下 C++ 相关的知识点,供大家学习参考~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪
🎏唠叨唠叨:在这个专栏里我会整理一些琐碎的 C++ 知识点,方便大家作为字典查询~

预处理命令

预处理概述

预处理是 C++ 的一个重要功能, 预处理由预处理程序负责完成。

预处理是指在进行编译的第一遍扫描(词法扫描和语法分析)之前所作的工作。

当对一个源文件进行编译时, 系统把自动引用预处理程序对源程序中的预处理部分作处理,处理完毕自动进入对源程序的编译。

C++ 提供了多种预处理功能,例如宏定义、文件包含、 条件编译等。合理地使用预处理功能编写的程序便于阅读、修改、 移植和调试,还有就是利于模块化程序设计

#include 其实就是一个预处理命令预处理,主要是处理以 # 开头的命令。预处理命令要放在所有函数之外,而且一般都放在源文件的前面。

常用预处理指令

//文件包含类
#include 包含一个源代码文件,头文件
//宏定义类
#define 定义宏
#undef 取消已定义的宏
//条件编译类
#if 如果给定条件为真,则编译下面代码
#ifdef 如果宏已经定义,则编译下面代码
#ifndef 如果宏没有定义,则编译下面代码
#elif 如果#if条件不为真,当前条件为真,则编译下面代码
#endif 结束#if...到 #else条件编译块

宏定义

C++ 源程序中允许用一个标识符来表示一个字符串,称为 “宏”。

被定义为宏的标识符称为 “宏名”。在编译预处理时,对程序中所有出现的宏名,都用宏定义中的字符串去代换,这称为宏替换或宏展开。

宏定义是由源程序中的宏定义命令完成的。

宏替换是由预处理程序自动完成的。在 C 语言中,宏定义分为有参数和无参数两种。

无参数宏定义
//语法
#define identify expression

#define 定义宏使用的关键字。
identify 宏的标识符,也就是宏名。
expression 该宏所代表的表达式或者常量值。    
//案例:
#define PI 3.14
//定义了一个宏 PI,其代表的常量值为 3.14,以后,我们需要使用 3.14 的地方,可以直接使用 PI 来代替。

案例

利用宏定义PI,输入半径r,完成求圆面积的代码。    
#define PI 3.1415926  
double r;
cin >> r;
cout << PI *r * r << endl;   
带参数宏定义
//语法
#define identify(paramlist) expression

#define 定义宏使用的关键字。
identify 宏的标识符,也就是宏名。
paramlist 宏的参数列表。
expression 该宏所代表的表达式或者常量值。

案例

#define INC(x) x++
//定义了一个宏 INC,该宏接受一个参数 x,该宏实现的功能是将当前 x 的值自增

//案例1
#define INC(v) v++
#define DEC(v ) v--
int num= 100;
cout << “num =<< num << endl;	//100
INC(num);
cout << “num =<< num << endl;	//101
DEC(num);
cout << “num =<< num << endl;	//100

//案例2
#define SQR(n) ((n)*(n))
int num = 10;
int result = SQR(num);
cout << result << endl;	//100
int result2 = SQR(5 + 5);
cout << result2 << endl;	//100

在使用宏参数时,建议将所有的参数都是要 () 括起来。

像函数参数一样,在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。

宏函数

C++ 中的宏函数,其实就是带参数的宏。

C++ 的宏函数跟普通函数类似,只是宏函数的参数没有类型

案例

利用宏函数,实现判断字符是否是十进制数字!    
#define DIGIT(c) ((c) >=0&& (c) <=9)
char ch1 = ‘a’;
char ch2 =2;
int d1 = DIGIT(ch1);
int d2 = DIGIT(ch2);
cout << d1 << endl;	//0
cout << d2 << endl;	//1

取消宏定义

定义了宏或者宏函数之后,如果不用了,可以使用 undef 取消定义宏和宏函数。

//语法
#undef MACRO_NAME

案例

#define PI 3.14
int main(){ 
    cout << "PI = " << PI << endl;
#undef PI
    cout << "PI = " << PI << endl; //报错
    return 0;
}
//#undef 取消定义了宏,取消定义宏之后,不可以再次访问该宏

条件编译

有些时候,希望当满足某条件时对一组语句进行编译,而当条件不满足时则编译另一组语句。条件编译功能可按不同的条件去编译不同的程序部分,从而产生不同的目标代码文件。这对于程序的移植和调试是很有用的。

在 C++ 中,一般情况下,源程序中所有的行都参加编译。但有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是 “条件编译”。

条件编译作用
  1. 屏蔽跨平台差异

    在大规模开发过程中,特别是跨平台和系统的软件里,可以在编译时通过条件编译设置编译环境。

  2. 包含程序功能模块

    可以使用 #ifdef 实现包含程序的不同的功能模块。

  3. 开关调试信息

    调试程序时,常常希望输出一些所需的信息以便追踪程序的运行。而在调试完成后不再输出这些信息,可以通过条件编译控制。

  4. 防止头文件重复包含

    头文件(.h)可以被头文件或 CPP 文件包含。由于头文件包含可以嵌套,CPP 文件就有可能多次包含同一个头文件;或者不同的 CPP 文件都包含同一个头文件,编译时就可能出现重复包含(重复定义)的问题。

#ifdef

C++ 的 #ifdef 用于判断,如果一个标识符已被 #define 命令定义过,那么就编译该段代码,否则不编译。同时,#ifdef 还可以配合 #else一起使用。

//语法
#ifdef identity 
	code1
#endif
//如果标识符 identity 被定义过了,那么就编译代码 code1,否则就不编译。                

//语法
#ifdef identity 
	code1
#else 
    code2
#endif
//如果标识符 identity 被定义过了,那么就编译代码 code1,否则就编译代码 code2。 

案例

//案例1
#include <iostream>
using namespace std;
int main(){ 
    cout << "测试条件编译" << endl;
#ifdef PRINT 
    cout << "PRINT has defined" << endl;
#endif
    return 0;
}

//案例2
#include <iostream>
using namespace std;
int main(){ 
    cout << "条件编译测试2" << endl;
#ifdef PR
    cout << "PR has defined" << endl;
#else 
    cout << "PR not defined" << endl;
#endif 
    return 0;
}
#ifndef

#ifndef正好和#ifdef反过来,用于判断,如果一个标识符没有被#define 命令定义过,那么就编译该段代码,否则不编译。就是if not define的意思。

//语法
#ifndef identity 
    code1
#endif
//如果标识符 identity 未被定义过,那么就编译代码 code1,否则就不编译。

//语法
#ifndef identity 
    code1
#else 
    code2
#endif
//#ifndef 也可以配合 #else 一起使用,这里说明,如果标识符 identity未被定义过,那么就编译代码 code1,否则就编译代码 code2。

案例

//案例1
#include <iostream>
using namespace std;
int main(){ 
    cout << "条件编译测试3" << endl;
#ifndef PR 
    cout << "PR not defined" << endl;
#endif
    return 0;
}

//案例2
#include <iostream>
using namespace std;
int main(){
    cout << "条件编译测试4" << endl;
#ifndef PR 
    cout << "PR not defined" << endl;
#else
    cout << "PR has defined" << endl;
#endif 
    return 0;
}
#if

C++ 的 #if 后面可以接常量表达式,如果常量表达式的值为真(非0),则对一段程序进行编译,否则对另一段程序进行编译。因此可使程序在不同条件下,完成不同的功能。

//语法1
#if expression 
    code1
#endif

//语法2
#if expression 
    code1
#else 
    code2
#endif

案例

//案例1
#include <iostream>
using namespace std;
int main(){ 
    cout << "条件编译测试5" << endl;
#define com 0
#if com 
    cout << "Start compile" << endl;
#endif
    return 0;
}

//案例2
#include <iostream>
using namespace std;
int main(){ 
    cout << "条件编译测试5" << endl;
#define com 0
#if com 
    cout << "Start compile" << endl;
#else 
    cout <<do not compile” << endl;
#endif
    return 0;
}
#elif

#elif可以跟在#if,#ifdef #ifndef的后面,但#else只能跟在最后面,用法和基本的条件语句类似。

案例

#include <iostream>
using namespace std;
int main() { 
    cout << "条件编译测试" << endl;
#define BY 0
#define BA 0
#if BY
    cout << "BY has define" << endl;
#elif BA
    cout << "BA is 1" << endl;
#endif
    return 0;}
#error

#error 用于在编译期间给出一个错误信息,并终止程序的编译。同时,#error 后面的错误信息不需要使用双引号。

//语法
#error error message

案例

#include <iostream>
using namespace std;
int main() { 
    cout << "条件编译测试" << endl
#error compile error here! 
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值