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

news/2025/2/3 17:48:42 标签: c语言, linux

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"

http://www.niftyadmin.cn/n/5840972.html

相关文章

初始Linux(7):认识进程(下)

1. 进程优先级 cpu 资源分配的先后顺序&#xff0c;就是指进程的优先权&#xff08; priority &#xff09;。 优先权高的进程有优先执行权利。配置进程优先权对多任务环境的 linux 很有用&#xff0c;可以改善系统性能。 还可以把进程运行到指定的CPU 上&#xff0c;这样一来…

leetcode27.删除有序数组中的重复项

目录 问题描述判题标准示例提示 具体思路思路一思路二 代码实现 问题描述 给你一个非严格递增排列的数组nums&#xff0c;请你原地删除重复出现的元素&#xff0c;使每个元素只出现一次&#xff0c;返回删除后数组的新长度。元素的相对顺序应该保持一致 。然后返回nums中唯一元…

数据库 - Sqlserver - SQLEXPRESS、由Windows认证改为SQL Server Express认证进行连接 (sa登录)

本文讲SqlServer Express版本在登录的时候&#xff0c; 如何由Windows认证&#xff0c;修改为Sql Server Express认证。 目录 1&#xff0c;SqlServer Express的Windows认证 2&#xff0c;修改为混合认证 3&#xff0c;启用sa 用户 4&#xff0c;用sa 用户登录 下面是详细…

探索 Copilot:开启智能助手新时代

探索 Copilot&#xff1a;开启智能助手新时代 在当今数字化飞速发展的时代&#xff0c;人工智能&#xff08;AI&#xff09;正以前所未有的速度改变着我们的工作和生活方式。而 Copilot 作为一款强大的 AI 助手&#xff0c;凭借其多样的功能和高效的应用&#xff0c;正在成为众…

计算机网络 性能指标相关

目录 吞吐量 时延 时延带宽积 往返时延RTT 利用率 吞吐量 时延 时延带宽积 往返时延RTT 利用率

攻防世界_php_rce(ThinkPHP框架)

打开靶场 点链接&#xff0c;发现是广告&#xff0c;没什么特别的&#xff0c;再看题目php.rce&#xff0c;查一下RCE是什么 RCE&#xff08;Remote Command Execution&#xff09;远程命令执行&#xff0c;是一种严重的网络安全漏洞。 RCE指攻击者能通过网络远程控制目标系统&…

在Ubuntu上使用Docker部署DeepSeek

在Ubuntu上使用Docker部署DeepSeek&#xff0c;并确保其可以访问公网网址进行对话&#xff0c;可以按照以下步骤进行&#xff1a; 一、安装Docker 更新Ubuntu的软件包索引&#xff1a; sudo apt-get update安装必要的软件包&#xff0c;这些软件包允许apt通过HTTPS使用存储库…

【漫话机器学习系列】075.隐含层(Hidden Layer)

隐含层&#xff08;Hidden Layer&#xff09; 在人工神经网络&#xff08;ANN&#xff09;中&#xff0c;隐含层是指输入层和输出层之间的层。它们由多个神经元&#xff08;或节点&#xff09;组成&#xff0c;这些神经元负责从输入层接收信号&#xff0c;进行处理后将信号传递…