✍个人博客: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++ 中,一般情况下,源程序中所有的行都参加编译。但有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部分内容指定编译的条件,这就是 “条件编译”。
条件编译作用
-
屏蔽跨平台差异
在大规模开发过程中,特别是跨平台和系统的软件里,可以在编译时通过条件编译设置编译环境。
-
包含程序功能模块
可以使用 #ifdef 实现包含程序的不同的功能模块。
-
开关调试信息
调试程序时,常常希望输出一些所需的信息以便追踪程序的运行。而在调试完成后不再输出这些信息,可以通过条件编译控制。
-
防止头文件重复包含
头文件(.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;
}