重回C语言之老兵重装上阵(十三)C 预处理器

C 语言预处理器


C 预处理器(Preprocessor)是编译过程中的一个重要阶段,它在编译器实际编译代码之前,对源代码进行文本替换和处理。预处理器的主要任务是处理指令以生成最终的代码,并为编译器提供准备工作。常见的预处理指令以 # 开头。

1. 宏定义 (#define)

#define 用来定义常量或宏,宏是由预处理器在编译时进行文本替换的。

示例:
#define PI 3.14159

此后,源代码中所有出现 PI 的地方都会被替换为 3.14159

宏函数:

可以使用 #define 定义宏函数,这样就可以进行更复杂的文本替换。

#define SQUARE(x) ((x) * (x))

此后,SQUARE(5) 会被替换成 ((5) * (5))


2. 条件编译 (#if, #ifdef, #ifndef, #else, #endif)

条件编译允许在编译过程中根据某些条件来包含或排除代码块。

示例:
#define DEBUG

#ifdef DEBUG
    printf("Debugging mode is enabled.\n");
#endif

如果定义了 DEBUG 宏,则会执行 printf 语句,否则会跳过。

  • #if:根据表达式的值判断是否编译某部分代码。
  • #ifdef:如果宏已定义,则编译相应部分。
  • #ifndef:如果宏没有定义,则编译相应部分。
  • #else:如果前面的条件不成立,则编译 #else 部分。
  • #endif:结束条件编译。

3. 文件包含 (#include)

#include 用于包含头文件,可以是标准库头文件,也可以是用户自定义的头文件。

示例:
#include <stdio.h>   // 包含标准库头文件
#include "myheader.h" // 包含自定义头文件
  • <filename>:用于包含标准库文件。
  • "filename":用于包含自定义的头文件,通常是相对路径。

4. 文件宏 (#line, #file)

这些指令用于改变源文件的行号和文件名,通常用于调试或生成错误信息时提供有用的调试信息。

示例:
#line 100 "newfile.c"

这会告诉编译器当前的文件为 newfile.c,并且当前行号为 100。


5. 预定义宏

C 预处理器提供了一些预定义的宏,它们在编译时自动存在。

  • __DATE__:表示当前日期,格式为 “Mmm dd yyyy”。
  • __TIME__:表示当前时间,格式为 “hh:mm:ss”。
  • __FILE__:表示当前源代码文件的路径。
  • __LINE__:表示当前源代码文件的行号。
示例:
printf("File: %s, Line: %d\n", __FILE__, __LINE__);

输出将会显示源文件名和当前行号。


6. 取消定义 (#undef)

#undef 用于取消已定义的宏。

示例:
#define PI 3.14159
#undef PI

这样,PI 宏就不再有效,如果再使用 PI,编译器会报错。


7. 代码连接 (#pragma)

#pragma 用于向编译器提供指令,它不是标准的一部分,不同的编译器可能会有不同的实现。常见的用途是控制编译警告或优化设置。

示例:
#pragma once

#pragma once 是一种防止头文件重复包含的方式,效果与 #ifndef#define#endif 类似。


8. 错误和警告处理 (#error, #warning)

预处理器指令 #error#warning 可以用来生成编译时错误或警告信息。

示例:
#error "This is an error message"

此时,编译器会报出一个错误,错误信息为 "This is an error message"


9. 预处理器的其他功能

文件合并

C 预处理器还支持文件合并,通常是在宏中使用 ## 连接两个标记。

#define CONCAT(a, b) a##b
int CONCAT(my, Var) = 5; // 变为 int myVar = 5;
字符串化

# 用于字符串化,它会将宏参数转换为字符串字面量。

#define TO_STRING(x) #x
printf(TO_STRING(Hello World)); // 输出 "Hello World"

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何建设一个企业级的数据湖

建设一个企业级的数据湖是一项复杂且系统化的工程&#xff0c;需要从需求分析、技术选型、架构设计到实施运维等多个方面进行综合规划和实施。以下是基于我搜索到的资料&#xff0c;详细阐述如何建设企业级数据湖的步骤和关键要点&#xff1a; 一、需求分析与规划 明确业务需…

如何在 macOS 上安装 PIP ?

PIP 是任何 Python 开发人员必备的工具&#xff0c;因为它简化了安装和管理 Python 包的过程。本教程是为 macOS 用户量身定制的&#xff0c;并假设对使用终端有基本的了解。 必备条件 在安装 PIP 之前&#xff0c;必须确保您的系统上已经安装了 Python。Python 3.4 及更高版…

Kotlin开发(六):Kotlin 数据类,密封类与枚举类

引言 想象一下&#xff0c;你是个 Kotlin 开发者&#xff0c;敲着代码忽然发现业务代码中需要一堆冗长的 POJO 类来传递数据。烦得很&#xff1f;别急&#xff0c;Kotlin 贴心的 数据类 能帮你自动生成 equals、hashCode&#xff0c;直接省时省力&#xff01;再想想需要多种状…

多版本并发控制:MVCC的作用和基本原理

多版本并发控制&#xff1a;MVCC的作用和基本原理 1、MVCC简介1.1 快照读与当前读的区别1.1.1 快照读1.1.2 当前读 1.2 数据库的读写问题1.3 MVCC的作用 2、MVCC实现原理之ReadView2.1 什么是ReadView2.2 ReadView的设计思路2.3 MVCC整体操作流程 1、MVCC简介 1.1 快照读与当前…

Docker—搭建Harbor和阿里云私有仓库

Harbor概述 Harbor是一个开源的企业级Docker Registry管理项目&#xff0c;由VMware公司开发。‌它的主要用途是帮助用户迅速搭建一个企业级的Docker Registry服务&#xff0c;提供比Docker官方公共镜像仓库更为丰富和安全的功能&#xff0c;特别适合企业环境使用。‌12 Harb…

HarmonyOS:创建应用静态快捷方式

一、前言 静态快捷方式是一种在系统中创建的可以快速访问应用程序或特定功能的链接。它通常可以在长按应用图标&#xff0c;以图标和相应的文字出现在应用图标的上方&#xff0c;用户可以迅速启动对应应用程序的组件。使用快捷方式&#xff0c;可以提高效率&#xff0c;节省了查…

从表人的相关单词聊起

英文单词是繁多的&#xff0c;甚至海量的&#xff0c;这和老外的思维方式有关&#xff0c;他们通常会为同一类事物的具体的东西或子类事物也专门创建一个单词来进行表达、表示或应对&#xff0c;这增加了表达的直接性和精确性&#xff0c;但是&#xff0c;也轻而易举地就创建出…

低代码系统-产品架构案例介绍、轻流(九)

轻流低代码产品定位为零代码产品&#xff0c;试图通过搭建来降低企业成本&#xff0c;提升业务上线效率。 依旧是从下至上&#xff0c;从左至右的顺序 名词概述运维层底层系统运维层&#xff0c;例如上线、部署等基础服务体系内置的系统能力&#xff0c;发消息、组织和权限是必…

2025年美赛B题-结合Logistic阻滞增长模型和SIR传染病模型研究旅游可持续性-成品论文

模型设计思路与创新点&#xff1a; 建模的时候应该先确定我们需要建立什么类的模型&#xff1f;优化类还是统计类&#xff1f;这个题需要大量的数据分析&#xff0c;因此我们可以建立一个统计学模型。 统计学建模思路&#xff1a;观察规律&#xff0c;建立模型&#xff0c;参…

自由学习记录(32)

文件里找到切换颜色空间 fgui中的 颜色空间是一种总体使用前的设定 颜色空间&#xff0c;和半透明混合产生的效果有差异&#xff0c;这种问题一般可以产生联系 动效就是在fgui里可以编辑好&#xff0c;然后在unity中也准备了对应的调用手段&#xff0c;可以详细的使用每一个具…

【2025AI发展预测】2.2025的风口与发展,我们如何主动拥抱这一浪潮

个人主页&#xff1a;Icomi 大家好我是一颗米&#xff0c;本系列文章包含我个人的一些思考见解&#xff0c;以及在网上看到的相关资讯&#xff0c;结合本人的认识&#xff0c;在那基础上进行加工输出&#xff0c;希望能帮助到各位&#xff0c;若您对本系列感兴趣&#xff0c;欢…

操作系统(Linux Kernel 0.11Linux Kernel 0.12)解读整理——内核初始化(main init)之硬盘初始化

前言 对硬盘和软盘块设备上数据的读写操作是通过中断处理程序进行的。内核每次读写的数据量以一个逻辑块(1024 字节)为单位&#xff0c;而块设备控制器则是以扇区(512字节)为单位访问块设备。在处理过程中&#xff0c;内核使用了读写请求项等待队列来顺序地缓冲一次读写多个逻…

利用机器学习创建基于位置的推荐程序

推荐系统被广泛应用于不同的应用程序中&#xff0c;用于预测用户对产品或服务的偏好或评价。在过去的几分钟或几小时里&#xff0c;你很可能在网上遇到过或与某种类型的推荐系统进行过互动。这些推荐系统有不同的类型&#xff0c;其中最突出的包括基于内容的过滤和协作过滤。在…

【AI论文】Video-MMMU:评估从多学科专业视频中获取知识的能力

摘要&#xff1a;人类通过三个认知阶段获取知识&#xff1a;感知信息、理解知识以及运用知识解决新问题。视频作为这一学习过程的有效媒介&#xff0c;促进了这些认知阶段的逐步推进。然而&#xff0c;现有的视频基准测试未能系统地评估大型多模态模型&#xff08;LMMs&#xf…

【C++高并发服务器WebServer】-9:多线程开发

本文目录 一、线程概述1.1 线程和进程的区别1.2 线程之间共享和非共享资源1.3 NPTL 二、线程操作2.1 pthread_create2.2 pthread_exit2.3 pthread_join2.4 pthread_detach2.5 patch_cancel2.6 pthread_attr 三、实战demo四、线程同步五、死锁六、读写锁七、生产消费者模型 一、…

C语言学习强化

前言 数据的逻辑结构包括&#xff1a; 常见数据结构&#xff1a; 线性结构&#xff1a;数组、链表、队列、栈 树形结构&#xff1a;树、堆 图形结构&#xff1a;图 一、链表 链表是物理位置不连续&#xff0c;逻辑位置连续 链表的特点&#xff1a; 1.链表没有固定的长度…

【C++探索之路】STL---string

走进C的世界&#xff0c;也意味着我们对编程世界的认知达到另一个维度&#xff0c;如果你学习过C语言&#xff0c;那你绝对会有不一般的收获&#xff0c;感受到C所带来的码云风暴~ ---------------------------------------begin--------------------------------------- 什么是…

【WebRTC - STUN/TURN服务 - COTURN配置】

在WebRTC中&#xff0c;对于通信的两端不在同一个局域网的情况下&#xff0c;通信两端往往无法P2P直接连接&#xff0c;需要一个TURN中继服务&#xff0c;而中继服务可以选用 COTURN 构建。 注&#xff1a;COTURN 是一个开源的 TURN&#xff08;Traversal Using Relays around…

React 前端框架实战教程

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 引言 React 是由 Facebook 开发的前端 JavaScript 库&#xff0c;旨在构建高效、灵活的用户界面&#xff0c;尤其适用于单页应用…

MiniMax-01中Lightning Attention的由来(线性注意力进化史)

目录 引言原始注意力线性注意力因果模型存在的问题累加求和操作的限制Lightning AttentionLightning Attention-1Lightning Attention-2 备注 引言 MiniMax-01: Scaling Foundation Models with Lightning Attention表明自己是第一个将线性注意力应用到如此大规模的模型&#…