c/c++的编译预处理

首先宏定义是把一个标识符替换成一个字符串,作用是替换文本,发生在编译预处理阶段,所以在这个阶段,系统不会检查语法的对错!


这个一直被我忽略,今天花一些时间来简单整理一下:

目录

宏定义

无参宏定义

带参宏定义

 条件编译

#ifdef  #else #endif 种类

#ifndef #else #endif 种类

#if #else #endif 种类


宏定义

无参宏定义

首先最简单的当然是无参宏定义,举个栗子:

#define PI 3.14 (包括#define 标识符 替换文本)

一般标识符大写,可以包括常量、关键字(int、struct、enum...)、表达式、语句等等字符串。标识符和文本间有空格,另外可以用\进行续行定义,如果在下面代码想要取消这个宏定义可以

#undef 标识符

带参宏定义

同时也可以可以选择带参数,在宏定义中叫做形参,在后续引用的时候叫实参,和函数的有些相似,可以像函数这样理解!

#define 宏名(形参) 替换文本

举一个栗子,例如MAX(a,b) 传入参数a和b去除较大的数

//取出a,b中较大的值,三目运算符
#define MAX(a,b) (a>b)?a:b

由于宏定义仅仅只是纯文本的替换,可能会计算出不是我们想要的结果,举个例子,理解这个例子,就会更了解在预处理的文本替换了

#include<iostream>
using namespace std;
#define F(x) x*x
#define G(x) (x)*(x)
int main()
{
	int a = 10;
	cout << F(a) << endl;//输出10*10的结果100
	cout << G(a) << endl;//输出(10)*(10)的结果100
	cout << F(2 + 8) << endl;//输出2+8*2+8的结果26
	cout << G(2 + 8) << endl;//输出(2+8)*(2+8)的结果100
	return 0;
}


 条件编译

 条件编译是在满足条件下,执行某一范围内的预处理,条件编译可以有效的防止重复定义

条件编译的几种形式

#ifdef  #else #endif 种类

第一种是标识段已被#define定义了,执行程序段1,否则执行2,有两种形式如下

#ifdef 标识符           #ifdef 标识符  //这种情况标识符前面定义过

代码段1                 代码段1

#else                  #endif

代码段2                

#endif

例如我写一个例子:方便理解

#include<iostream>
using namespace std;
#define DEBUG
int main()
{
#ifdef DEBUG//这里是前面预定义过的,所以执行代码1
	cout << "现在在执行代码1!" << endl;
#else
	cout << "现在在执行代码2!" << endl;
#endif

#ifdef DEBUG2//这里前面没有预定义过,执行第二段代码
	cout << "现在在执行第一段代码!" << endl;
#else
	cout << "现在在执行第二段代码!" << endl;
#endif
	return 0;
}

#ifndef #else #endif 种类

第二种,就是前面定义过就执行第二段代码,否则第一段,在此只写一下定义,可以把上面代码都加一个n测试

#ifndef 标识符           #ifndef 标识符  //这种情况标识符前面未定义

代码段1                  代码段1

#else                   #endif

代码段2                

#endif

#if #else #endif 种类

这一种非常像选择分支语句if,else语句,常量表达式不为0,执行代码1,否则执行代码段2,容易理解,语法如下

#if 常量表达式

代码段1

#else 

代码段2

#endif

  这其中通过条件编译只预定义其中某一范围内的代码,可以有效的防止头文件重复!在vs2019中也可以用#pragma once只预处理一次解决。OK,终于整理好了,如果看到的小伙伴发现其中的错误,可以留言我修改一下,谢谢!



版权声明:本文为m0_61973596原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。