c语言预处理
第十七章 联合体和枚举第十八章 动态内存管理第十九章 文件操作第二十章编译和链接文章目录前言一、预处理是什么二、使用1.预处理符号2.#define定义常量3.#define定义宏4.宏替换的规则5.宏函数的对比6.#和##总结前言随着嵌入式开发和系统编程的不断发展C语言这门基础语言也越来越重要很多人都开始学习C语言本文就介绍了C语言预处理的核心内容。一、预处理是什么预处理是C语言编译过程中的第一阶段它在编译器正式编译之前对源代码进行文本层面的处理。预处理指令以#开头主要包括宏定义、文件包含、条件编译等。二、使用1.预处理符号c语言设置了一些预处理符号是可以直接使用的例如__FILE__//进行编译的源文件__LINE__//文件当前的行号__DATE__//文件被编译的日期__TIME__//文件被编译的时间__STDC__//如果编译器遵循ANSI C其值为1否则未定义2.#define定义常量有时候我们会遇到需要反复使用某个值的场景为了方便我们可以把它定义为常量。基本语法为#define name stuff#defineMAX1000//定义常量MAX 1000#defineregregister//为register这个关键字//创建一个简短的名字#definedo_foreverwhile(1)//用更形象的符号替换实现#defineCASEbreak;case//写case语句的时候自动把// break加上//如果stuff过长可以在每行后面加上反斜杠分成几行写#defineDEBUG_PRINTprintf(file:%s\tline:%d\t\ date%s\ttime:%s\n,\__FILE__,__LINE__,\__DATE__,__TIME__)在用define定义的时候最好不要再后面加上分号否则在某些语句下面可能会出现错误。例如#defineMAX1000;if(...)maxMAX;这里因为没有大括号的时候if后面只能用一条语句如果有两条就会报错。3.#define定义宏#define还可以把参数替换到文本中这种实现通常称为宏。#define name(parament-list) stuff其中parament-list是 一个由逗号隔开的符号表它们可能出现在stuff中。参数的左括号必须要与name紧邻如果之间有空白存在参数列表就会把这个解释为stuff的一部分。例子#defineSQUARE(x)x*x这个宏接收参数x如果你把SQUARE5放置在程序中预处理器就会把他替换成表达式5*5但是这个宏存在问题inta5;SQUARE(a1);我们这里想着的是把6传进去但是实际上替换之后得到的是a1*a1运算的顺序变了所以正确的写法应该是在后面的宏定义加上括号这样就能达到我们想要的效果。#define SQUARE(x) (x)*(x)还有一种宏定义会出现问题#defineDOUBLE(x)(x)(x)inta5;intnum10*DOUBLE(a)这里我们预期的结果是100但是运行之后发现输出结果是55我们把它替换后发现得到的代码是10*55运算顺序是乘法先算为了解决这个问题我们要在外面再加一个括号。#define DOUBLE(x) ((x)(x))通过上面的例子我们可以得出结论对于数值表达式进行求值的宏定义都应该加上括号以避免运算的时候参数中的操作符或者临近操作符之间不可预料的相互作用。某些宏参数还会带有副作用如果宏参数在宏定义中出现超过一次并且宏参数带有副作用那么在使用宏的时候就可能出现危险导致不可预测的后果。副作用是参数求值的时候出现的永久性效果。#defineMAX(a,b)((a)(b)?(a):(b))x4;y5;zMAX(x,y);这里整体替换如下z ((x)(y)?(x):(y));此时x等于5y等于7z等于6并不能得到我们想要的结果如果想要得到正确的结果我们只需要把x和y改成1即可就没有副作用了。4.宏替换的规则在程序中扩展#define定义符号和宏的时候需要涉及几个步骤1.在调用宏的时候首先对参数进行检查查看是否包含任何由#define定义的符号如果有就仙贝替换。2.替换文本插入到程序原来文本的位置对于宏参数名被他们的值所替换。3。最后再次对结果文件进行扫描查看是否包含由#define定义的符号如果有则重复上面的过程。注意1.宏参数和#define定义中可以出现其他由#define定义的符号但是对于宏不能出现递归。2.当预处理器搜索#define定义的符号的时候字符串常量的内容不被搜索。5.宏函数的对比宏通常由于执行简单的运算比如在两个数中找到一个更大的数。对比函数来说宏在程序的规模和速度方面会更胜一筹而且宏参数与类型无关而函数需要在类型合适的表达式中使用。当然宏也有他的弊端1.使用宏的时候如果宏很长就会大幅度增加程序的长度。2.宏无法调试3.宏由于类型无关因此也不够严谨4.宏会带来运算符优先级的问题下面是宏与函数的对比表格对比项宏函数代码长度每次使用时都会插入宏代码可能使程序变长函数代码只保存一份每次调用只增加调用开销执行速度预处理时直接替换无调用开销速度更快有函数调用和返回的开销速度稍慢操作符优先级容易因缺少括号产生优先级问题函数参数在调用时求值优先级由函数内部决定参数类型与类型无关任何类型都可传入需要与函数参数类型匹配副作用参数可能被多次求值产生不可预测的副作用参数只在调用时求值一次无副作用问题调试宏在预处理阶段已替换无法调试函数可以设置断点方便调试递归宏不能递归函数支持递归6.#和###运算符能将宏参数转化成字符串的字面量仅允许出现在带参数的宏的替换列表中。#运算符所执行的操作可以理解为“字符串化”。假如我们有一个变量a10当我们想要打印出“the value of a is 10.”我们就可以这样写#define PRINT(n) printf(“the value of”#nis %d.,n)当我们调用PRINTa的时候就会把n替换成a#n替换成#a就转换成“a”##可以把位于两边的符号合成一个符号被称为记号粘连。但是这个东西基本上用不到。最多是在宏定义生成函数的时候通过##生成函数名。例如#defineGENERIC_MAX(type)type type##_max(type x,type y){return(xy?x:y);}一般我们约定宏名全部大写函数名不全部大写来区分宏和函数。使用#undef可以移除一个宏定义总结例如以上就是今天要讲的内容本文仅仅简单介绍了C语言预处理的使用而预处理提供了大量能使我们快速便捷地处理代码的功能和方法如宏定义、文件包含、条件编译等。

相关新闻

企业获客软件导出限额测评方法与数据:9款产品对比

企业获客软件导出限额测评方法与数据:9款产品对比

这篇按统一维度测了9款企业获客软件的每日导出次数和条数限制。为什么每日导出限额对团队规模这么关键?如果是1人单干,每天要用的名单量本身有限,大多数平台的每日额度基本都够用,导出限额很少会成为瓶颈。但换成5人以上的团队&am…

2026/9/30 5:08:30 阅读更多 →
人生具象化的术语大全的庖丁解牛

人生具象化的术语大全的庖丁解牛

总纲:人生具象化,是把脑海里模糊、抽象、飘在空中的想法、目标、感受,转化成看得见、可衡量、能落地的实体信息。抽象想法只存在想象,无法执行;具象化就是把虚的念头翻译为实的指标、画面、行动清单。 具象化不是空想许…

2026/9/29 0:59:32 阅读更多 →
人生客观现实的术语大全的庖丁解牛

人生客观现实的术语大全的庖丁解牛

总纲:客观现实,是独立于个人想法、情绪、愿望、想象而存在的真实世界。不会因为你希望它怎样,它就变成什么样;也不会因为你拒绝、逃避、抱怨,就自动消失。 客观现实不以人的主观世界模型为转移。我们内心的愿望、感受、…

2026/9/29 5:36:50 阅读更多 →

最新新闻

Windows Server 2012 R2远程桌面多用户并发配置全指南

Windows Server 2012 R2远程桌面多用户并发配置全指南

1. 为什么默认装完Windows Server 2012 R2根本不能多人同时远程登录?刚接手一台新部署的Windows Server 2012 R2物理机,客户急着要让5个部门主管同时远程接入做报表——我连RDP连接都还没点开,就发现事情不对劲:第一个用户登录后&…

2026/9/30 7:59:33 阅读更多 →
鸿蒙Flutter隐式动画实战:AnimatedContainer原理与调试

鸿蒙Flutter隐式动画实战:AnimatedContainer原理与调试

1. 项目缘起:在鸿蒙上做 Flutter 动画,到底难不难把 Flutter 的 AnimatedContainer 拿到鸿蒙跨平台开发里讲,这是很多人第一眼觉得“有什么好讲”的话题。但真在鸿蒙设备上跑起来后你会发现,动画不生效、跳变、掉帧这类问题&#…

2026/9/30 7:59:33 阅读更多 →
Flutter AnimatedContainer隐式动画原理与鸿蒙适配实践

Flutter AnimatedContainer隐式动画原理与鸿蒙适配实践

Flutter 的隐式动画组件我差不多每天都在用,但真正让我对它彻底改观,是在把项目往鸿蒙上迁移的时候。原本以为这种“属性变化自动补间”的封装会带来额外性能损耗,实测下来反而成了跨端一致性最好的部分——不管是在 Android、iOS 还是鸿蒙上…

2026/9/30 7:59:33 阅读更多 →
SRC漏洞挖掘实战指南:从零基础到稳定赚取赏金的完整路径

SRC漏洞挖掘实战指南:从零基础到稳定赚取赏金的完整路径

刚开始挖 SRC 漏洞的时候,很多人以为这是个大牛才能干的事,觉得没有几年渗透功底,连门都摸不到。后来我带过几个零基础的朋友入行,看着他们从连 HTTP 抓包都看不懂,到陆续提交出有效漏洞、拿到第一笔赏金,我…

2026/9/30 7:59:33 阅读更多 →
Windows Server 2012 多用户远程桌面配置全指南

Windows Server 2012 多用户远程桌面配置全指南

简介:本资源是一份面向系统管理员与IT运维人员的Windows Server 2012多用户远程桌面配置实操指南,解决企业环境中单台服务器需支持多人并发远程管理的实际需求。文档详细覆盖三大核心配置:启用远程桌面服务、禁用“用户限制到单独会话”策略、…

2026/9/30 7:59:33 阅读更多 →
用Flask构建校园部门资料管理系统:从需求到部署全流程解析

用Flask构建校园部门资料管理系统:从需求到部署全流程解析

每年开学季,我参与的学生会部门总会陷入同一种混乱:换届后上一届的策划案、制度文件、成员名单散落在好几个人的网盘和QQ群里,想找一份三年前的部门总结,得在聊天记录里翻半天;想统计一下部门成员信息,Exce…

2026/9/30 7:58:33 阅读更多 →

日新闻

Base64 图片头部特征识别:从文件头到格式判断的完整指南

Base64 图片头部特征识别:从文件头到格式判断的完整指南

1. 项目概述:为什么说看懂 base64 图片头部是基本功这几年跟 base64 打交道的机会越来越多,后端接口返回图片、前端渲染验证码、小程序里存小图、还有一些老系统导出报表,动不动就给你一段长到怀疑人生的 base64 字符串。很多人拿到字符串就直…

2026/9/30 0:00:35 阅读更多 →
Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

Java公交站牌广告管理系统:JSP+Servlet+MySQL实战落地指南

简介:本资源是一份面向Java初学者与课程设计学生的公交站牌广告灯箱管理系统毕业设计文档,聚焦城市公共广告资源信息化管理痛点,提供从需求分析到技术实现的完整方案。文档采用标准学术论文结构,含摘要、英文摘要、目录及五章正文…

2026/9/30 0:00:35 阅读更多 →
用 Redis Lua 构建大模型 API 多租户原子配额治理体系

用 Redis Lua 构建大模型 API 多租户原子配额治理体系

我去年年底接了一个内部 AI 平台的治理需求,背景很直接:公司把 DeepSeek、MiniMax 这类大模型 API 统一封装成内部网关,开放给几个业务团队用。结果第一个月账单出来,额度直接超了 4 倍。仔细查日志,发现原因并不复杂—…

2026/9/30 0:00:35 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/29 8:16:59 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/29 16:41:41 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/9/29 8:24:48 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/29 19:29:29 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/29 5:58:00 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/29 3:55:56 阅读更多 →