C语言:预处理
文章目录前言本文旨在系统性地介绍C语言中的预处理。一、预定义符号二、#define定义宏2.1、#define定义标识符无参宏2.2、宏定义中括号的使用2.3、带有副作用的宏参数2.4、宏替换的规则2.5、宏和函数的对比三、命名约定四、#undef五、条件编译六、头文件包含6.1、头文件被包含的方式6.2、嵌套文件包含前言本文旨在系统性地介绍C语言中的预处理。一、预定义符号预定义符号是编译器预先定义的宏可直接使用无需 #define。它们在预处理阶段被替换为对应的值。__FILE__//进⾏编译的源⽂件名__LINE__//⽂件当前的⾏号__DATE__//⽂件被编译的⽇期__TIME__//⽂件被编译的时间__STDC__//如果编译器遵循ANSI C其值为1否则未定义代码示例#includestdio.hintmain(){printf(文件%s\n,__FILE__);printf(行号%d\n,__LINE__);printf(编译日期%s\n,__DATE__);printf(编译时间%s\n,__TIME__);return0;}二、#define定义宏宏定义允许将参数替换到文本中其语法形式如下#definename(parament-list)stuffname宏名(parament-list)参数列表由逗号分隔的符号表stuff替换文本参数可以出现在其中注意事项参数列表的左括号必须紧挨宏名不能有空格。如果有空格参数列表被当成替换文本。2.1、#define定义标识符无参宏基本语法#definenamestuff代码示例#defineMAX1000#defineregregister// 为 register 关键字起简短别名#definedo_foreverfor(;;)// 用形象符号替换无限循环#defineCASEbreak;case// case 语句自动加 break当 stuff 过长时可以用反斜杠\续写符分行编写最后一行不加告诉预处理器下一行是当前行的延续在预处理阶段会合并成一行。如果没有续行符,预处理后宏定义只到第一行结束后面的内容被当作普通代码导致编译错误。代码示例#defineDEBUG_PRINTprintf(file:%s\tline:%d\t\date:%s\ttime:%s\n,\__FILE__,__LINE__,\__DATE__,__TIME__)末尾不建议加分号否则可能引发语法错误。代码示例#defineMAX1000;if(condition)maxMAX;// 替换后 → max 1000;;// 替换后if 和 else 之间变成两条语句导致编译错误。elsemax0;2.2、宏定义中括号的使用宏定义中给每个参数加上括号再给整个表达式加上括号可以避免因操作符优先级导致的意外结果。①参数未加括号宏是纯文本替换参数中的操作符优先级影响计算顺序#defineSQUARE(x)x*xSQUARE(a1)// 替换后 → a 1 * a 1// 实际计算a (1 * a) 1// 结果与预期不符解决办法给宏体的每个参数加上括号。#defineSQUARE(x)(x)*(x)SQUARE(a1)// 替换后 → (a 1) * (a 1)②整个宏体未加括号宏体本身没有括号导致外部运算符影响计算顺序#defineDOUBLE(x)(x)(x)10*DOUBLE(a)// 替换后 → 10 * (5) (5)// 实际计算10 * 5 5 55解决办法给整个宏体加上括号。#defineDOUBLE(x)((x)(x))10*DOUBLE(a)// 替换后 → 10 * ((5) (5)) 1002.3、带有副作用的宏参数宏参数在宏体中多次出现时带副作用的参数会被多次求值导致不可预测的结果。应避免在宏参数中使用 、-- 等操作或用函数替代宏。副作用是指表达式求值时永久改变变量值的效果。x1;// 无副作用x 不变x;// 有副作用x 被修改代码示例#includestdio.h#defineMAX(a,b)((a)(b)?(a):(b))intmain(){intx5;inty8;// 宏调用MAX(x, y)// 预处理后展开为((x) (y) ? (x) : (y))// 执行过程// ① 比较 (x) (y)即 5 8假此时 x6y9// ② 条件为假执行 (y)取 y 的当前值 9 赋给 z然后 y 变为 10// ③ 最终x6y10z9intzMAX(x,y);printf(x%d y%d z%d\n,x,y,z);return0;}2.4、宏替换的规则① 参数检查检查宏参数是否包含 #define 定义的符号如果有则先替换② 文本插入将替换文本插入到宏调用的位置参数名被对应的值替换③ 再次扫描对结果文件再次扫描检查是否还有 #define 定义的符号如果有则重复上述过程代码示例#definePI3.14#defineAREA(r)(PI*(r)*(r))doublesAREA(5);替换过程①检查参数 5没有 #define 定义的符号②插入替换文本(PI * (5) * (5))③再次扫描发现 PI 是 #define 定义的符号④替换 PI(3.14 * (5) * (5))。注意事项①宏不能递归宏不能调用自身②字符串内容不搜索字符串字面量中的内容不会被宏替换。代码示例#definePI3.14printf(PI %f,PI);// 宏被替换printf(PI);// 字符串中的 PI 不会被替换2.5、宏和函数的对比对比项宏Macro函数Function执行时机预处理阶段展开运行时调用执行效率高无调用开销低有调用和返回开销代码长度大型宏多次展开使程序膨胀代码只存一份类型检查无有调试无法调试可逐语句调试类型通用类型无关参数类型固定参数为类型可以如 MALLOC(10, int)不可以副作用风险参数多次求值参数只求值一次内存开销不占栈空间每次调用占用栈空间递归不可递归可递归操作符优先级易受邻近操作符影响安全参数先求值三、命名约定宏名全部大写函数名不要全部大写C语言本身没有区分目的是让代码可读性更强便于区分宏和函数。四、#undef#undef 指令用于移除一个已存在的宏定义。如果需要重新定义一个宏名或取消某个宏的作用可以先用 #undef 移除旧定义。语法形式#undefNAME代码示例#includestdio.h#defineMAX100// 此时 MAX 已定义#undefMAX// 移除 MAX 的宏定义// 此时 MAX 未定义不能再使用#ifdefMAXprintf(MAX 已定义\n);#elseprintf(MAX 未定义\n);#endif五、条件编译条件编译用于在预处理阶段根据条件决定哪些代码被保留、哪些被丢弃常用于调试信息控制、头文件保护和跨平台适配。常见条件编译指令①单分支条件编译#if常量表达式// 表达式为真时编译#endif#define__DEBUG__1#if__DEBUG__printf(调试模式\n);// 被编译#endif②多分支条件编译#defineVERSION2#ifVERSION1printf(版本1\n);#elifVERSION2printf(版本2\n);#elseprintf(其他版本\n);#endif③判断是否被定义写法含义#if defined(symbol)symbol 已定义时为真#ifdef symbol同上简写#if !defined(symbol)symbol 未定义时为真#ifndef symbol同上简写#defineDEBUG#ifdefDEBUGprintf(调试模式\n);// 被编译#endif#ifndefRELEASEprintf(非发布模式\n);// 不被编译#endif④嵌套条件编译#ifdefined(OS_UNIX)#ifdefOPTION1unix_version_option1();#endif#ifdefOPTION2unix_version_option2();#endif#elifdefined(OS_MSDOS)#ifdefOPTION2msdos_version_option2();#endif#endif六、头文件包含6.1、头文件被包含的方式包含方式查找路径适用场景#include xxx.h直接去标准系统路径查找库文件标准库、第三方库#include “xxx.h”先在当前源文件所在目录查找找不到再去标准路径查找本地头文件项目自定义库文件也可以用 “” 包含但是查找效率低不易区分是库还是本地文件。6.2、嵌套文件包含头文件被重复包含// test.c#includetest.h#includetest.h#includetest.h#includetest.h#includetest.h预处理后test.h 的内容会被拷贝 5 次导致代码膨胀和编译压力增加。解决方案1头文件守卫条件编译#ifndef__TEST_H__#define__TEST_H__// 头文件的内容voidtest();structStu{intid;charname[20];};#endif// __TEST_H__解决方案2#pragma once#pragmaonce// 头文件的内容voidtest();structStu{intid;charname[20];};

相关新闻

从零开始学Python:写给初学者的实用开发路线

从零开始学Python:写给初学者的实用开发路线

一个只停留在“看完语法教程”阶段的Python学习者,和一个真正能上手开发项目的程序员,差距往往不在智商,而在有没有一条清晰的路线图。很多人学Python学到中途放弃,不是因为难,而是因为漫无目的地刷教程,把…

2026/8/24 13:00:56 阅读更多 →
单片机毕设选题推荐:基于 STM32 的多模式智能家居环境监测控制系统设计 基于 STM32 单片机的光照温湿度采集与自动调控系统设计(018204)

单片机毕设选题推荐:基于 STM32 的多模式智能家居环境监测控制系统设计 基于 STM32 单片机的光照温湿度采集与自动调控系统设计(018204)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

2026/8/24 13:00:56 阅读更多 →
单片机毕设选题推荐:基于单片机的水温、PH、浑浊度一体化监测系统设计 基于 51/STM32 单片机的水环境多传感器数据采集报警系统(018104)

单片机毕设选题推荐:基于单片机的水温、PH、浑浊度一体化监测系统设计 基于 51/STM32 单片机的水环境多传感器数据采集报警系统(018104)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

2026/8/24 13:00:56 阅读更多 →

最新新闻

智慧校园安防与能耗革新:智能门锁如何破解高校后勤管理痛点

智慧校园安防与能耗革新:智能门锁如何破解高校后勤管理痛点

随着智慧校园数字化建设持续深化,高校宿舍、教学教室、实训功能房、会议室等核心场景的精细化管理,成为后勤运维升级的核心抓手。传统校园长期依赖机械钥匙管控、人工逐间查寝、固定时段通断电的粗放管理模式,普遍存在学生身份核验松散、外来…

2026/8/24 15:37:46 阅读更多 →
抖音批量下载工具完整教程:4 步跑通无水印全站归档

抖音批量下载工具完整教程:4 步跑通无水印全站归档

抖音批量下载工具完整教程:4 步跑通无水印全站归档 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support.…

2026/8/24 15:37:46 阅读更多 →
如何把 ASI 插件加载进任意游戏:Ultimate ASI Loader 配置与使用

如何把 ASI 插件加载进任意游戏:Ultimate ASI Loader 配置与使用

如何把 ASI 插件加载进任意游戏:Ultimate ASI Loader 配置与使用 【免费下载链接】Ultimate-ASI-Loader The Ultimate ASI Loader is a proxy DLL that loads custom .asi libraries into any game process. 项目地址: https://gitcode.com/gh_mirrors/ul/Ultimat…

2026/8/24 15:37:46 阅读更多 →
MMD Tools 插件完整指南:在 Blender 中导入 .pmx 模型与 .vmd 动作

MMD Tools 插件完整指南:在 Blender 中导入 .pmx 模型与 .vmd 动作

MMD Tools 插件完整指南:在 Blender 中导入 .pmx 模型与 .vmd 动作 【免费下载链接】blender_mmd_tools MMD Tools is a Blender addon for importing/exporting Models and Motions of MikuMikuDance. 项目地址: https://gitcode.com/gh_mirrors/bl/blender_mmd_…

2026/8/24 15:37:46 阅读更多 →
AMD锐龙逐核调压不用进BIOS:SMUDebugTool 5分钟实操笔记

AMD锐龙逐核调压不用进BIOS:SMUDebugTool 5分钟实操笔记

AMD锐龙逐核调压不用进BIOS:SMUDebugTool 5分钟实操笔记 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: https://…

2026/8/24 15:36:46 阅读更多 →
ConcurrentHashMap是如何保证线程安全的?

ConcurrentHashMap是如何保证线程安全的?

先记住一句最核心的话&#xff1a;JDK8 的 ConcurrentHashMap 通过 CAS synchronized volatile 等机制&#xff0c;在保证线程安全的同时尽量减少锁竞争。重点是&#xff1a;它不是整张 Map 加一把大锁。一、先理解为什么 HashMap 线程不安全假设&#xff1a;Map<String, …

2026/8/24 15:36:46 阅读更多 →

日新闻

前端内容安全与依赖审计实践

前端内容安全与依赖审计实践

前端内容安全与依赖审计实践 前端安全依赖分层防护。没有任何单一配置能替代输出编码、权限校验和依赖更新。 把不可信内容当作数据 默认使用框架的转义能力&#xff1b;确需渲染 HTML 时&#xff0c;先在服务端或可信的客户端库中进行白名单过滤。避免把用户输入直接赋给 inne…

2026/8/24 1:08:15 阅读更多 →
Windows登录密码存储机制全解析:从哈希算法到安全加固实战

Windows登录密码存储机制全解析:从哈希算法到安全加固实战

1. 项目概述&#xff1a;Windows登录密码的“黑匣子”每次你按下CtrlAltDel&#xff0c;输入密码&#xff0c;然后看到那个熟悉的桌面&#xff0c;这背后发生了一系列复杂而精密的操作。作为一名长期与Windows系统打交道的从业者&#xff0c;我经常被问到&#xff1a;“我的密码…

2026/8/24 1:08:15 阅读更多 →
AI面试系统安全挑战与解决方案

AI面试系统安全挑战与解决方案

1. 项目概述&#xff1a;AI面试系统的安全挑战去年参与某跨国企业AI面试系统部署时&#xff0c;遇到一个典型案例&#xff1a;候选人在视频面试中无意提到竞争对手产品名称&#xff0c;系统竟自动将该信息关联到企业知识库并生成竞品分析报告。这个看似"智能"的功能&…

2026/8/24 1:08:15 阅读更多 →

周新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态&#xff0c;宏观上观察到的光是由无数个微观的光量子组成的&#xff0c;每个光子在产生的瞬间&#xff0c;其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前&#xff0c;在微观层面&#xff0c;每个光量子的运动轨迹是以波函数所展现…

2026/8/24 0:06:02 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”&#xff0c;而是SIP会话的动态重定向你有没有遇到过这样的场景&#xff1a;客服坐席A正在和客户通电话&#xff0c;突然需要把这通对话无缝转给专家坐席B&#xff0c;客户完全感知不到中间的断连——既没听到忙音&#xff0c;也没被要求重新拨号…

2026/8/24 0:20:20 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack&#xff1f;如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法&#xff0c;那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/24 0:14:11 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速&#xff1a;macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/23 18:47:06 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南&#xff1a;3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗&#xff1f;ncmdump解密工具帮你轻松解决这个困…

2026/8/23 12:10:44 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片&#xff1a;为英语学习 App 打造桌面级学习助手适用平台&#xff1a;HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0&#xff08;API 26 Beta&#xff09;新增了 AgentCard 智能体卡片能力&#xff0c;这是继 HMAF&#xff08;鸿蒙智能体框架&#x…

2026/8/24 11:20:22 阅读更多 →