C++学习贴---C++预处理器

文章目录

  • 前言
  • 预处理器
    • #define预处理
    • 条件编译
      • #ifdef
      • #ifndef
      • #if、#elif、#else 和 #endif
    • #和##运算符
  • 预定义宏

前言


预处理器

预处理器是指一些指示编译器在实际编译之前所需要完成的指令。

预处理器负责处理以**井号(#)**开头的预处理指令,这些指令在编译过程之前对源代码进行一些文本替换和操作。

例如#include <iostream>

除此之外,还有#define、#if、#else、#line 等


#define预处理

#define: 用于定义宏,将一个标识符替换为特定的文本。宏在代码中可以起到类似函数的作用,但是是在编译时进行文本替换的。

#define PI 3.14159

示例:

#include <iostream>// 定义常量 PI
#define PI 3.14159int main() {// 使用定义的常量 PIdouble radius = 5.0;double area = PI * radius * radius;// 输出计算结果std::cout << "半径为 " << radius << " 的圆的面积是: " << area << std::endl;return 0;
}

在上述中,用了#define PI 3.14159 这样预处理器会将所有出现的PI替换成3.14159,实际上,编译器处理的代码应该是:

double area = 3.4159  * radius * radius;

除了用#define定义常量的宏之外,还可以定义带有参数的宏;

如:

#include <iostream>// 定义带参数的宏
#define MAX(x, y) ((x) > (y) ? (x) : (y))int main() {int a = 10, b = 7;// 使用定义的宏int result = MAX(a, b);// 输出计算结果std::cout << "较大的数是: " << result << std::endl;return 0;
}

在实际编译时,预处理器会将所有的MAX(a, b)替换为((a) > (b) ? (a) : (b)),从而实现参数的替换和宏的展开。


条件编译

条件编译: 使用#if、#ifdef、#ifndef、#elif、#else和#endif等指令来根据条件选择性地包含或排除代码块。

#ifdef

#ifdef 是一个预处理器指令,用于在编译时检查一个标识符是否已经被定义。如果指定的标识符已经定义,则预处理器会包含后续的代码块,否则会忽略这个代码块。

使用示例:

#include <iostream>// 定义一个标识符
#define DEBUG_MODEint main() {// 检查标识符是否已经定义#ifdef DEBUG_MODEstd::cout << "Debug mode is enabled." << std::endl;#elsestd::cout << "Debug mode is disabled." << std::endl;#endifreturn 0;
}

在上述中使用了#define DEBUG_MODE 预定义了一个标识符,后面在main函数中,通过#ifdef DEBUG_MODE来检查。如果存在就会打印Debug mode is enabled.

上述运行结果:
在这里插入图片描述
如果我们将#define DEBUG_MODE注释掉,就会有
在这里插入图片描述

#ifndef

这个和#ifdef正好是相反的结果,即如果给定的标识符尚未被定义,则包括代码块。

#if、#elif、#else 和 #endif

这些预处理器指令允许根据条件选择性地包括或排除代码块。

示例:

#include <iostream>#define DEBUG_LEVEL 2int main() {#if DEBUG_LEVEL == 0std::cout << "No debugging." << std::endl;#elif DEBUG_LEVEL == 1std::cout << "Basic debugging." << std::endl;#elif DEBUG_LEVEL == 2std::cout << "Advanced debugging." << std::endl;#elsestd::cout << "Unknown debugging level." << std::endl;#endifreturn 0;
}

#和##运算符

#和 ## 是两个特殊的运算符,用于在宏定义中进行字符串化和连接操作。

#运算符(字符串化操作符): 在宏定义中,# 运算符可以将参数转换为字符串常量。在宏的定义中,将参数用 # 运算符括起来,预处理器会将参数的文本形式转换为字符串。

示例:

#define STRINGIZE(x) #xint main() {int value = 42;const char* str = STRINGIZE(value);// 在这里,str 的值为 "value"return 0;
}

STRINGIZE(value) 会被替换为 “value”,因为 #x 将参数 x 转换为字符串。

##运算符(连接操作符): 在宏定义中,## 运算符用于将两个标识符连接在一起,形成一个新的标识符。

#define CONCAT(a, b) a##bint main() {int xy = 42;// 在这里,CONCAT(x, y) 会被替换为 xyreturn 0;
}

在上述代码中,CONCAT(x, y) 会被替换为 xy,因为 a##b 将两个参数 a 和 b 连接在一起。


预定义宏

C++ 中有一些预定义的宏,它们由编译器提供,并可在程序中直接使用。这些宏通常用于提供有关编译环境和代码特性的信息。

例如:

  • __cplusplus: 这个宏用于指示 C++ 的版本。如果程序是在 C++ 编译器中编译的,__cplusplus 的值会被设置为一个表示 C++ 版本的整数。
  • FILE: 这个宏会被替换为当前源文件的文件名。
  • LINE: 这个宏会被替换为当前源文件中的行号。
  • funcFUNCTION: 这个宏会被替换为当前函数的名称。
  • DATETIME: 这两个宏会被替换为程序被编译时的日期和时间。

简短的示例:

#include <iostream>
using namespace std;int main ()
{cout << "Value of __LINE__ : " << __LINE__ << endl;cout << "Value of __FILE__ : " << __FILE__ << endl;cout << "Value of __DATE__ : " << __DATE__ << endl;cout << "Value of __TIME__ : " << __TIME__ << endl;return 0;
}

编译和运行后结果:

Value of __LINE__ : 6
Value of __FILE__ : test.cpp
Value of __DATE__ : Feb 28 2011
Value of __TIME__ : 18:52:48

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/138388.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

lv11 嵌入式开发 ARM体系结构理论基础(异常、微架构)4

1 异常概念 处理器在正常执行程序的过程中可能会遇到一些不正常的事件发生 这时处理器就要将当前的程序暂停下来转而去处理这个异常的事件 异常事件处理完成之后再返回到被异常打断的点继续执行程序 2 异常处理机制 不同的处理器对异常的处理的流程大体相似&#xff0c…

BMVC 23丨多模态CLIP:用于3D场景问答任务的对比视觉语言预训练

来源&#xff1a;投稿 作者&#xff1a;橡皮 编辑&#xff1a;学姐 论文链接&#xff1a;https://arxiv.org/abs/2306.02329 摘要&#xff1a; 训练模型将常识性语言知识和视觉概念从 2D 图像应用到 3D 场景理解是研究人员最近才开始探索的一个有前景的方向。然而&#xff0c…

地区 IP 库

地区 & IP 库 yudao-spring-boot-starter-biz-ip (opens new window)业务组件&#xff0c;提供地区 & IP 库的封装。 #1. 地区 AreaUtils (opens new window)是地区工具类&#xff0c;可以查询中国的省、市、区县&#xff0c;也可以查询国外的国家。 它的数据来自 …

kubectl声明式资源管理命令

目录 一、声明式资源管理介绍&#xff1a; 二、声明式相关命令&#xff1a; 1. 语法格式&#xff1a; 2. 查看资源配置清单&#xff1a; 3. 解释资源配置清单&#xff1a; 4. 修改资源配置清单并应用&#xff1a; 4.1 离线修改&#xff1a; 4.2 在线修改&#xff1a; 5. 删除资…

【qemu逃逸】XCTF 华为高校挑战赛决赛-pipeline

前言 虚拟机用户名: root 无密码 设备逆向与漏洞分析 程序没有去符合, 还是比较简单. 实例结构体如下: 先总体说一下流程: encode 为 base64 编码函数, decode 为 base64 解码函数. 然后 encPipe 和 decPipe 分别存放编码数据和解码数据, 分别有四个: 其中 EncPipeLine 中…

ElementUI的el-upload上传组件与表单一起提交遇到的各种问题以及解决办法(超详细,每个步骤都有详细解读)

背景: 使用ruoyi-vue进行2次开发,需要实现表单与文件上传一起提交,并且文件上传有4个,且文件校验很复杂,因此ruoyi-vue集成的上传组件FileUpload调试几天后发现真不太适用,最终选择element UI原生组件el-upload(FileUpload也是基于el-upload实现的),要实现表单与文件同…

Unity地面交互效果——4、制作地面凹陷轨迹

大家好&#xff0c;我是阿赵。   上一篇介绍了曲面细分着色器的基本用法和思路&#xff0c;这一篇在曲面细分的基础上&#xff0c;制作地面凹陷的轨迹效果。 一、思路分析 这次需要达到的效果是这样的&#xff1a; 从效果上看&#xff0c;这个凹陷在地面下的轨迹&#xff0…

PostMan授权认证使用

Authorization 对于很多应用&#xff0c;出于安全考虑我们的接口并不希望对外公开。这个时候就需要使用授权(Authorization)机制。 授权过程验证您是否具有访问服务器所需数据的权限。 当发送请求时&#xff0c;通常必须包含参数&#xff0c;以确保请求具有访问和返回所需数据…

蓝桥杯算法竞赛第一周题型总结

本专栏内容为&#xff1a;蓝桥杯学习专栏&#xff0c;用于记录蓝桥杯的学习经验分享与总结。 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;C &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&#x1f69a; &#x1f339;&#x1f33…

skynet学习笔记02— skynet介绍、skynet基础API与环境变量

01、Skynet与Actor模型 在系统Skynet之前&#xff0c;先了解一下Skynet与Actor模型&#xff0c;下列是风云大佬的介绍以及一个大佬的博客 https://github.com/cloudwu/skynet/wiki/GettingStartedhttps://blog.csdn.net/qq769651718/article/details/79432793 02、Skynet基础…

kafka开启SSL认证(包括内置zookeeper开启SSL)

zookeeper和kafka的SSL开启都可单独进行 生成SSL证书 使用jre自带的keytool工具生成&#xff0c;linux和windows下生成的证书可以通用 生成含有一个私钥的keystore文件&#xff0c;有效期10年&#xff08;本文证书密码统一使用test123&#xff09; keytool -genkeypair -ali…

acwing算法基础之搜索与图论--朴素版dijkstra算法

目录 1 基础知识2 模板3 工程化 1 基础知识 朴素版dijkstra算法的关键步骤&#xff1a; 初始化d[1]0&#xff0c;d[2~n]正无穷&#xff0c;例如0x3f3f3f3f。用集合S来表示当前已被确定最小距离的结点们。遍历每一个结点&#xff1a;找到不在S中的且距离结点1最近的结点&#…

python升级pip的时候一直失败

如图,一直提示使用 python.exe -m pip install --upgrade pip 进行升级pip,但是执行这句命令又不成功.然后综合了几篇文章以后使用了下面的命令可以升级了 python -m pip install --upgrade pip --user -i https://mirrors.aliyun.com/pypi/simple/ 主要是在推荐的语句上使用…

润色论文Prompt

你好&#xff0c;我现在开始写论文了&#xff0c;我希望你可以扮演帮我润色论文的角色我写的论文是关于xxxxx领域的xxxxx&#xff0c;我希望你能帮我检查段落中语句的逻辑、语法和拼写等问题我希望你能帮我检查以下段落中语句的逻辑、语法和拼写等问题同时提供润色版本以符合学…

K8S篇之Pod中的资源限额

1、Pod定义requests、limits相关参数 在k8s中&#xff0c;全面限制一个应用及其中的pod所能占用的资源配额&#xff0c;具体可以使用下面三种方式&#xff1a; 1、定义每个pod的资源配额相关参数&#xff0c;如CPU/memory的request、limits&#xff1b; 2、自动为每个没有定义资…

AI搞钱——工具篇之视频、音频转文字

AI搞钱 工具篇之视频、音频转文字Memo AI &#xff1a;本地的语音转文字工具WhisperpyvideotransnottaAccurate AI万兴优转 视频转换 压缩工具v14.1.19.20 工具篇之视频、音频转文字 哈喽各位小伙伴们&#xff01;今天我要给大家推荐几款视频、音频转文字的好用工具。 Memo A…

Android Studio新建项目下载依赖慢,只需一个操作解决

新建的安卓工程&#xff0c;下载依赖贼慢怎么办&#xff1f;水一篇吧。 首先新建工程&#xff0c;建好以后项目就自动开始下载了&#xff0c;底部开始出现进度条&#xff0c;但是进度条一直不怎么动&#xff0c;网速也就十几k&#xff0c;要是等他下载得下一天。 直入主题&…

第四节(2):修改WORD中表格数据的方案

《VBA信息获取与处理》教程(10178984)是我推出第六套教程&#xff0c;目前已经是第一版修订了。这套教程定位于最高级&#xff0c;是学完初级&#xff0c;中级后的教程。这部教程给大家讲解的内容有&#xff1a;跨应用程序信息获得、随机信息的利用、电子邮件的发送、VBA互联网…

AttributeError: module ‘tensorflow‘ has no attribute ‘contrib‘解决办法

在TensorFlow2环境下执行1.X版本的代码时报错&#xff1a; AttributeError: module ‘tensorflow‘ has no attribute ‘contrib‘ 当然第一时间想到的是利用 如下代码 来解决问题&#xff08;大部分情况都是这样&#xff09;&#xff0c; tf.compat.v1但是又出现以下报错 Att…

Django之三板斧的使用,全局配置文件介绍,request对象方法,pycharm链接数据库,Django链接数据库,ORM的增删改查

【1】三板斧(3个方法)的使用 Httpresponse() 括号内写什么字符串&#xff0c;返回的就是什么字符串返回的是字符串 render(request&#xff0c; 静态文件 ) request是固定的静态文件是写在templates文件夹里面的&#xff0c;如&#xff0c;HTML文件 redirect( 重定向的地址 ) 重…