新闻详情

新闻详情

首页 / 资讯中心 / 详情

c语言预处理

发布时间:2026/9/27 22:57:50来源:尧图网络
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语言预处理的使用而预处理提供了大量能使我们快速便捷地处理代码的功能和方法如宏定义、文件包含、条件编译等。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

苹果序列号查询全解析:从底层逻辑到二手交易避坑实战 2026/9/27 23:49:49

苹果序列号查询全解析:从底层逻辑到二手交易避坑实战

1. 苹果序列号查询的底层逻辑与核心价值很多人第一次接触“序列号查询”这个概念,是因为买了一台二手 iPhone 或者 Mac,想确认卖家说的“全新未激活”“国行正品”到底靠不靠谱。苹果的序列号就像设备的身份证号,它不只是一串随机字符&#x…

阅读更多 →
Laravel Lang 中库尔德语(ckb)翻译完成度报告:15 个缺失键位全解析与补全指南 2026/9/27 23:49:49

Laravel Lang 中库尔德语(ckb)翻译完成度报告:15 个缺失键位全解析与补全指南

后端 【免费下载链接】lang List of 128 languages for Laravel Framework, Laravel Jetstream, Laravel Fortify, Laravel Breeze, Laravel Cashier, Laravel Nova and Laravel UI. 项目地址: https://gitcode.com/gh_mirrors/la/lang 点击查看 免费下载 本指南以…

阅读更多 →
3个坑让你省5万:内蒙古高等级公路建设开发有限责任公司网站对比评测 2026/9/27 23:49:49

3个坑让你省5万:内蒙古高等级公路建设开发有限责任公司网站对比评测

3个坑让你省5万:内蒙古高等级公路建设开发有限责任公司网站对比评测 找建站公司最怕什么?不是功能做不全,而是报价单上那些看不懂的术语,最后结账时才发现多花了几万块冤枉钱。很多老板拿着需求去问价,销售嘴里蹦出“微服务架构”、“全栈云原生”,转…

阅读更多 →
UG数控编程从入门到精通:工艺思维与实战避坑指南 2026/9/27 23:49:49

UG数控编程从入门到精通:工艺思维与实战避坑指南

1. 为什么UG数控编程值得你花时间啃下来干了十几年机加工,从手编宏程序到现在的CAM软件,我最大的感受就是:UG(现在官方叫Siemens NX)在数控编程这块,依然是国内模具、汽车、航空零件加工厂里最硬的那块敲门…

阅读更多 →
基于YOLOv8的多端车流检测系统源码拆解与实战调优 2026/9/27 23:49:43

基于YOLOv8的多端车流检测系统源码拆解与实战调优

简介:本资源是一套基于YOLOv8构建的多端车流检测系统完整源码包,面向计算机视觉学习者、交通监控方向开发者及需要目标检测实战项目的学生与工程师,帮助其快速搭建可运行的车辆流量检测应用。压缩包共396个文件,约16.93MB&#xf…

阅读更多 →
Java数字签名与证书生成实战:从keytool到Bouncy Castle全解析 2026/9/27 23:49:43

Java数字签名与证书生成实战:从keytool到Bouncy Castle全解析

简介:围绕Java数字签名与数字证书的源码示例,面向中高级Java开发者及安全编程初学者,演示如何在网络通信中利用非对称加密保障数据完整性与发送方身份验证。压缩包为RAR格式,体积仅17KB,便于快速下载与阅读&#xff1b…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉