当前位置: 首页 > news >正文

预处理指令简介

预处理指令(preprocessor directives)是在编译之前由预处理器(preprocessor)处理的特殊指令。也就是说,预处理是编译的“前戏”,不是正式程序的一部分。好比我们要自驾游,得约好同伴吧?得打包行李吧?可能还得提前沐浴更衣、做个拉皮拍个黄瓜啥的,这些都是自驾游的前戏。自驾游时,我们眼脑四肢并用,打火,挂档,给油,看路,瞟导航,这些操作就像我们在敲代码。然后汽车通过电流、拉线、齿轮将我们的操作翻译为电信号和机械传动,这相当于编译。最后发动机点火启动、油门开闭、齿轮啮合、转向、车轮转动就是程序执行了。

预处理指令比较特别,全部以#字符开头。这个符号就是用作和程序代码作区分的,告诉编译器在正式编译之前得先关照一下井边的同志。

预处理器指令的主要类型包括:

1.宏定义(Macro Definition)

#define:定义一个宏。之前咱们讲过,宏表现为“一沙一世界,一叶一菩提”,就是用一小串字符表示一大段代码。你可以把宏想象成一个包装袋。

宏有两种具体应用,可以是一个标识符(不带参数的宏)或是一个宏函数(带参数的宏)。

#undef:取消已定义的宏。

2.文件包含(File Inclusion)

#include:这个指令可以说是喜闻乐见、每日必备。它的实际疗效是将一个源文件的内容包含(插入)到#include指令所在的位置。这允许程序员将代码分布在多个文件中,并在需要时将它们组合起来。每个文件都能单独执行,整合在一起还能搞出更大的阵仗,这就像自驾油我们约玩伴组成个车队一样。

#include指令有两种形式:使用尖括号<>包含标准库头文件,使用双引号""包含用户自定义头文件或特定目录中的文件。

3.条件编译(Conditional Compilation)

像if语句一样(只不过写法不一样),如果满足一定的条件,就将某段代码进行编译,不满足就不编译。这样做是为了根据不同的编译环境或条件(如操作系统类型、编译器选项等)包含或排除特定的代码段。好比我们看天气打包行李,天气不好就要带上雨具。

(1)#if、#elif、#else、#endif:这些指令用于根据条件编译代码。预处理器会检查#if或#elif后面的常量表达式,如果为真(非零),则编译对应的代码段。#else部分(如果有的话)会在前面的条件都不满足时编译。#endif用于结束条件编译块。

(2)#ifdef、#ifndef:这些指令分别用于检查某个宏是否已定义或未定义。如果条件满足,则编译对应的代码段。

4.其他预处理器指令

(1)#error:咱们在编译时总会被提示代码存在这样那样的错误,这些错误是编译器帮我们检测的。如果我们想自己设定某种情况下显示某种错误信息,就要用到#error指令。#error指示编译器在编译时生成一个给定的错误信息,常将它嵌入到条件编译结构中,这样可以基于编译时的条件来决定是否触发这个错误。

(2)#warning:和#error差不多,只不过它输出的不是错误信息,而是警告。

(3)#line:用于将下一行代码的行号、文件名设置为指定的行号、文件名,并且后续行的行号从这个指定行号开始递增。

(4)#pragma:用于向编译器发出指令,有哪些指令由编译器厂商自行定义,因此不同的编译器可能支持不同的 #pragma 指令。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Mapreduce_csv_averageCSV文件计算平均值
  • 白盒测试-发送请求
  • 前端面试题整理-浏览器
  • 云开发微信小程序--即时聊天(单人聊天,多人聊天室)
  • 【走迷宫】
  • (回溯) LeetCode 77. 组合
  • Node.js中判断是文件还是文件夹的多种方法
  • Web语义化及实际应用
  • 奥运科技观察:AI PC,如何成为当代体育精神的数字捍卫者?
  • 搭建知识中台:让企业告别低效率
  • proc文件系统
  • 【MySQL】mysql异常宕机无法启动处理过程
  • 探索数据可视化,数据看板在各行业中的应用
  • (贪心 + 双指针) LeetCode 455. 分发饼干
  • 16 交换机命令行配置
  • Git的一些常用操作
  • Odoo domain写法及运用
  • Redis的resp协议
  • Selenium实战教程系列(二)---元素定位
  • Vue.js-Day01
  • 道格拉斯-普克 抽稀算法 附javascript实现
  • 机器学习 vs. 深度学习
  • 扑朔迷离的属性和特性【彻底弄清】
  • 全栈开发——Linux
  • 实战:基于Spring Boot快速开发RESTful风格API接口
  • 通过git安装npm私有模块
  • 一些关于Rust在2019年的思考
  • Java数据解析之JSON
  • # Pytorch 中可以直接调用的Loss Functions总结:
  • #Linux(权限管理)
  • #我与Java虚拟机的故事#连载19:等我技术变强了,我会去看你的 ​
  • $(this) 和 this 关键字在 jQuery 中有何不同?
  • (C++二叉树05) 合并二叉树 二叉搜索树中的搜索 验证二叉搜索树
  • (力扣记录)1448. 统计二叉树中好节点的数目
  • (论文阅读40-45)图像描述1
  • (亲测成功)在centos7.5上安装kvm,通过VNC远程连接并创建多台ubuntu虚拟机(ubuntu server版本)...
  • (深入.Net平台的软件系统分层开发).第一章.上机练习.20170424
  • (十八)devops持续集成开发——使用docker安装部署jenkins流水线服务
  • (数位dp) 算法竞赛入门到进阶 书本题集
  • (算法)Travel Information Center
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • (转)shell中括号的特殊用法 linux if多条件判断
  • *算法训练(leetcode)第四十五天 | 101. 孤岛的总面积、102. 沉没孤岛、103. 水流问题、104. 建造最大岛屿
  • .Net 6.0--通用帮助类--FileHelper
  • .NET Core工程编译事件$(TargetDir)变量为空引发的思考
  • .Net MVC4 上传大文件,并保存表单
  • .NET版Word处理控件Aspose.words功能演示:在ASP.NET MVC中创建MS Word编辑器
  • .NET微信公众号开发-2.0创建自定义菜单
  • .NET中统一的存储过程调用方法(收藏)
  • .vollhavhelp-V-XXXXXXXX勒索病毒的最新威胁:如何恢复您的数据?
  • [ 隧道技术 ] 反弹shell的集中常见方式(二)bash反弹shell
  • []串口通信 零星笔记
  • [16/N]论得趣
  • [20180312]进程管理其中的SQL Server进程占用内存远远大于SQL server内部统计出来的内存...
  • [2023年]-hadoop面试真题(一)