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

「C/C++」C/C++预处理器

在这里插入图片描述

博客主页:何曾参静谧的博客
文章专栏:「C/C++」C/C++学习

目录

  • 一、宏替换 #define
    • 1. 定义常量
    • 2. 定义函数
    • 3. 定义代码块
  • 二、条件编译 #if
    • 1. 使用 `#ifdef`、 `#else` 和 `#endif`
    • 2. 使用 `#if` 、`#elif`、`#else`和 `#endif` 编译不同版本的代码
    • 3. 使用 `#ifndef` 和 `#define`和`#endif`防止头文件重复包含
  • 三、头文件包含 #include
    • 1. 头文件两种写法
    • 2.C语言头文件
    • 3.C++常用头文件


一、宏替换 #define

宏是一种预处理器指令,它可以将一些代码片段或者常量直接替换为另一些内容,在编译过程中被展开为相应的代码或者值。通过定义宏,我们可以简化编写代码的工作量,并且通过修改宏的定义,可以方便地进行代码的修改。例如,我们可以使用#define来定义宏:

注意事项:

  • 宏定义的名称通常使用大写字母,并使用下划线来分隔单词。
  • 宏定义必须以 #define 开头,定义的常量、函数、代码块等必须是合法的C语句。
  • 宏定义可以包含参数,从而使得宏可以在不同的场景下进行重用。
  • 宏定义可以使用反斜杠(\)对代码进行换行,以便于阅读和维护。
  • 宏定义在代码被编译之前就会被预处理器处理,所以宏定义是一种文本替换的手段,替换的过程是简单的字符串替换,因此要特别注意宏定义带来的潜在问题,比如优先级、参数的多次计算等等。

1. 定义常量

这个宏定义了一个名为 PI 的常量,并将其值设定为 3.1415926。
例子中PI会被替换成3.14159

#define PI 3.1415926

2. 定义函数

这个宏定义了一个名为 MAX 的函数,并使用三目运算符定义了其功能,即返回两个参数中的较大值。
例子中,MAX(a,b)会被替换成((a)>(b)?(a):(b))。

#define MAX(a, b) ((a) > (b) ? (a) : (b))

3. 定义代码块

在预处理过程中,宏会被直接替换成相应的值

#define DO_SOMETHING { \printf("Hello, "); \printf("world!"); \
}

二、条件编译 #if

条件编译是一种预处理技术,可以根据一些特定条件来决定编译哪些代码,从而实现不同平台、不同版本程序的定制。 预处理器提供了一些指令用于条件编译,如#if、#ifdef、#ifndef、#else以及#endif等。这些指令可以方便地控制代码的编译。例如:

指令作用
#ifdef如果定义了某个宏,则编译下面的代码。
#ifndef如果没有定义某个宏,则编译下面的代码。
#if根据条件编译下面的代码。
#else当上一个条件不成立时,编译下面的代码。
#elif当上一个条件不成立时,根据新条件编译下面的代码。
#endif结束一个条件编译模块。

1. 使用 #ifdef#else#endif

编译不同平台的代码

#ifdef _WIN32// Windows 平台下的代码#include <windows.h>
#else// 非 Windows 平台下的代码#include <unistd.h>
#endif

定义导出dllexport

#if defined(_WIN32)
#define DllExport __declspec(dllexport)
#else
#define DllExport
#endif

定义导出dllimport

#if defined(_WIN32) && !defined(WNT_STATIC_LINK)
#    define UFUNEXPORT       __declspec(dllimport)
#    define UFUNGLOBAL       extern __declspec(dllimport)
#else
#    define UFUNEXPORT
#    define UFUNGLOBAL       extern
#endif
#ifndef LIBNXOPENUICPP_EXPORTS_HXX_INCLUDED
#define LIBNXOPENUICPP_EXPORTS_HXX_INCLUDED
#	   if defined(_WIN32) && !defined(WNT_STATIC_LINK)
#		   define NXOPENUICPPEXPORT	   __declspec(dllimport)
#		   define NXOPENUICPPGLOBAL	   extern __declspec(dllimport)
#		   define NXOPENUICPPTEMPLATE	 extern
#	   else
#		   define NXOPENUICPPEXPORT
#		   define NXOPENUICPPGLOBAL	   extern
#		   define NXOPENUICPPTEMPLATE
#	   endif
#endif  /*  LIBNXOPENUICPP_EXPORTS_HXX_INCLUDED  */

2. 使用 #if#elif#else#endif 编译不同版本的代码

#define VERSION 3#if VERSION == 1// 版本 1 的代码
#elif VERSION == 2// 版本 2 的代码
#elif VERSION == 3// 版本 3 的代码
#else// 其他版本的代码
#endif

3. 使用 #ifndef#define#endif防止头文件重复包含

#ifndef _MY_HEADER_H_
#define _MY_HEADER_H_/* 这里是头文件的内容 */#endif /* _MY_HEADER_H_ */

三、头文件包含 #include

头文件包含了一些函数和变量的声明,方便进行程序编写。比如常用的stdio.h、stdlib.h、string.h等头文件就包含了常见的输入输出、内存操作等函数的声明。预处理器的指令#include可以用于包含头文件,例如:#include<stdio.h>、#include"myHead.h"

1. 头文件两种写法

用尖括号<>括起来
表示该头文件是标准库文件或系统文件,编译器会在标准库和系统包含路径中查找该头文件。

#include <iostream>

用双引号""括起来
表示该头文件是用户自定义的文件,编译器会在当前编译文件所在目录下查找该头文件。

#include "myHeader.h"

2.C语言头文件

头文件描述
#include<stdio.h>包含输入输出常用函数,如printf、scanf、fprintf、fscanf等。
#include<stdlib.h>包含常用的标准库函数,如malloc、free、exit、atoi等。
#include<string.h>包含字符串处理函数,如strcpy、strcat、strlen等。
#include<math.h>包含常用的数学函数,如sin、cos、sqrt、ceil等。
#include<time.h>包含日期和时间函数,如time、ctime、gmtime等。
#include<ctype.h>包含字符处理函数,如isalnum、isalpha、isdigit等。
#include<stdbool.h>包含布尔变量类型。
#include<limits.h>包含整型变量的范围限制。
#include<float.h>包含浮点型变量的范围限制。

3.C++常用头文件

头文件描述
#include<iostream>C++标准输入输出流,包含了输入输出相关的函数和对象,如cin、cout、cerr、clog等。
#include<string>包含字符串处理函数,如substr、size、length等。
#include<cstdlib>包含C++标准库的通用函数,如stdlib库中的malloc和free函数、字符串处理函数等。
#include<cctype>包含字符处理函数,如isalpha、isdigit等。
#include<cmath>包含数学函数,如sin、cos、sqrt、ceil等。
#include<vector>定义了vector类,支持动态数组操作。
#include<algorithm>包含STL(标准模板库)算法函数,如sort、max_element、min_element等。
#include<map>定义了map类,支持快速查找、插入、删除等操作。
#include<set>定义了set类,支持快速查找、插入、删除等操作。
#include<fstream>C++文件输入输出流,支持文本和二进制文件的读写操作。

在这里插入图片描述

http://www.lryc.cn/news/65445.html

相关文章:

  • java语言入门教程文章
  • 基于灰狼算法的极限学习机(ELM)回归预测-附代码
  • 【五一创作】ERP实施-委外业务-委外采购业务
  • DAY 54 数据库基础
  • 网络编程 总结二
  • 消息称苹果Type-C口充电未设MFi限制,iOS17将更新Find My服务
  • 设计模式——工厂模式(简单工厂、工厂方法、抽象工厂)
  • 《C语言技术体系》 学习路线总目录 + 思维导图
  • 数字图像处理简答题
  • 【Java校招面试】基础知识(五)——GC
  • 使用CMake调用Makefile 项目
  • 快速傅里叶变换FFT学习笔记
  • 如何下载安装驱动
  • 鸿蒙Hi3861学习四-Huawei LiteOS介绍
  • Vue核心 收集表单数据 过滤器
  • 华为EC6108V9E/EC6108V9I_rk3228_安卓4.4.4_通刷_卡刷固件包
  • 数字化转型导师坚鹏:面向数字化转型的大数据顶层设计实践
  • day27_mysql
  • QwtPlotCurve使用说明
  • JS逆向 -- 某平台登录加密分析
  • 一分钟快速实现Flask框架的蓝图和视图
  • Mysql 约束练习【第13章_约束】
  • java调用cmd命令
  • Qt音视频开发36-超时检测和自动重连的设计
  • Reactor 第九篇 WebFlux重构个人中心,效果显著
  • Vben Admin 自学记录 —— Drawer组件的基本使用及练习(持续更新中...)
  • Android 9.0 根据包名默认授予app悬浮窗权限
  • Swift中Data,String,[UInt8]的相互转换(6种互相转换)
  • 【微软Bing王炸更新】无需等待,人人可用,答案图文并茂,太牛了
  • 腾讯云的cdn怎么配置|腾讯云CDN配置教程