前言
使编译器执行预处理操作的代码被称为预处理指令,本文介绍常见的预处理指令的实际用法。
一、预处理符号
预处理符号是C语言内置的符号,是可以直接使用的。
(相关资料图)
其中,若遵顼ANSI C,则__STDC__
为1,否则未定义。
二、#define
1)定义标识符
#define可以用来定义标识符,其语法为:#define name stuff
,经过预处理后,stuff
会被直接替换为·name
。
若stuff
的内若过长,可在句末加上\
续行符号,像这样:
#include#define Piccaso "Pablo,Diego,José\Francisco,de,Paula,Juan,Nepomuceno\,María,de,los,Remedios,Cipriano,de\,la,Santísima,Trinidad,Ruiz,y,Picasso"int main(){printf("%s", Piccaso);return 0;}
示例1:数值替换
int main(){int a = 100;return 0;}
示例2:循环替换
#includeint main(){while(1){printf("A");}return 0;}
运行代码,将会在屏幕上死循环地打印A
。
示例3:分支替换
int main(){int input = 0;switch (input){case 1:break; case 2:break; case 3:}return 0;}
2)宏定义
#define允许有参数的文本替换,这种操作通常称为宏,其语法为:#define name(list) stuff
,其中,list
是由逗号隔开的符号表,符号有可能出现在stuff
中。
示例1:
int main(){printf("%d", 5+5);return 0;}
示例2:
int main(){printf("%d", 10*double(5+1));return 0;}
因为#define
的功能只是替换,若要利用宏定义实现快捷的函数操作,最好的方法是在宏定义时多加括号,以便于达到整体求值的效果,像这样:#define double(x) (x)+(x)
。
注意:由于宏是直接替换,因此传参时严禁使用自增,自减,传参时使用,替换后依然会再次执行,会导致不可预测的后果。
3)字符串转换符
字符串有自动连接的特点,例如运行以下这段代码:
#includeint main(){printf("123" "456");return 0;}
效果图:
字符串转换符#就是利用这个特性,它可以将宏定义中传入的参数,替换为字符串格式。
#include#define sum(x) printf("the val of "#x" is %d",x)int main(){int a = 10;sum(a);return 0;}
在上述代码中,#号
将a
直接转化为字符串,随后三个字符串拼接在一起。
效果图:
利用该方法可以只传参一次实现值和名
同时打印。
4)片段链接符
在宏定义时,片段连接符##
可以实现将两个符号连接在一起,使其成为一个符号,前提是这个合成的符号必须已经被定义。
#include#define double(x) sum##x*=2int main(){int sum1 = 1;int sum2 = 1;int sum3 = 1;double(1);printf("%d %d %d", sum1, sum2, sum3);return 0;}
在上述代码中,##
会把sum和参数x连接在一起,当我们传入1经过预处理后,等效于:sum1*=2
。
效果图:
5)宏定义VS函数
宏定义的优势:
宏定义的执行速度远远超过函数,当执行简单的计算时,更适合使用宏定义。宏定义传参时没有类型检测,可以将任意的数据传入。宏定义是直接替换,可以传入各种各样的符号,实现许许多多函数做不到的功能。(可以传入类型、传入函数、传入语句等等)宏定义的劣势:
宏定义不能调试、不能递归,因此宏定义只适合做简单的计算。宏定义是直接替换,因此相邻操作符的优先级很有可能产生不期望的顺序,因此要尽可能带括号。宏定义传参没有类型检测,因此不够严谨。6)命名公约
以下几条公约,必须遵守
宏定义的名必须全部大写。函数名不可以全部大写。三、#undef#undef
宏定义删除,可以在函数内部使用!被删除后的标识就不能再使用了。
四、命令行编译
指在VScode
或Linux
等用命令行执行编译的环境下,可以在编译时对变量进行赋值。
五、条件编译
在写程序时,有些代码是为了查看某个部分是否正确而写的的调试代码。
删除很可惜,但又不想让其编译,此时就可以使用选择性编译
。
但实质上使用if
语句或直接注释
会更加方便,但在C语言内置的头文件中,为了节约时间经常使用条件编译。
1)常量表达式判断
#if 常量表达式//...#endif
常量表达式为真,则中间的语句编译;
常量表达式为假,则中间的语句不编译。
此外,也可以写成多分支的表达式条件编译。
int main(){#if 0printf("111");#elif 1printf("222");#else 0printf("333");#endifreturn 0;}
效果图:
2)是否定义判断
判断某个符号是否被定义,只要被定义,就编译中间的语句,无论其被定义为什么。
#include#define MAXint main(){#if defined(MAX)//或#ifdef MAXprintf("111");#endifreturn 0;}
或判断某个符号是否没定义,没定义则编译。
#include#define MAXint main(){#if !defined(MAX)//或#ifndef MAXprintf("111");#endifreturn 0;}
3)嵌套判断
条件编译是可以互相嵌套的。
#include#define DEBUG int main(){#ifdef DEBUG#if 1printf("111");#elif 0printf("222");#endif#endif return 0;}
如上述代码是在是否定义判断中嵌套常量表达式判断。
效果图:
六、头文件的包含
1)双引号与尖括号
对于#include
来说,后面的文件有两种引用方法:
所有的头文件在包含时都可以使用双引号,但为了速度和区别位置,建议自己写的头文件用双引号,标准库中的用尖括号。
2)头文件的嵌套包含
可以将许许多多的头文件都包含在一个自己创建的头文件中,最后只需要在其他的源文件中包含该自己创建的头文件即可,像这样:
3)头文件重复包含解决方法
在写多人合作的大型项目时,每个程序员可能都要包含一次公用的头文件,当他们写的代码汇总时,这个头文件可能会被包含多次。
因此,我们使用条件编译来解决这个问题。
#if !defined(TIME)#define TIME //...//... //在这里实现各种函数//...#endif
假设上述代码为head.h
,当我们第一次包含head.h
时,由于TIME没有被定义,因此会定义一个TIME,同时编译里面的函数。
当我们第二次包含head.h
时,因为TIME被定义过了,即使head.h
里面的内容被拷贝到源文件中,也不会进行编译,从而加快了速度。
注意:在头文件开头加入#pragma once
即可一键实现上述效果,不必冗杂的代码,但仅限于自己写的头文件,标准库的头文件已经帮你加完了。
感谢您的阅读与耐心~
关键词: 编程算法
(责任编辑:黄俊飞)推荐内容
- 天天百事通!预处理指令用法详解(C语言)
- 赵氏家谱全部的字辈-天天播报
- 从前初识这世间 歌词_从前初识这世间万
- 怎样推广品牌 推广品牌的方法 播报
- 青海探索公立医院改革:建设国家区域医疗
- 当日快讯:辽宁鞍山:房交会优惠政策期间
- 账单日和还款日是什么意思 账单日和还款
- 世界今日报丨生益电子(688183.SH)2022年
- 雄韬股份收关注函:货币资金仅15.23亿,
- 全球动态:没有信用卡可以分期买手机吗
- 今日热门!*ST海创股价分析 *ST海创60055
- 逐步了解如何制作 550 绳手链
- 惠誉:房地产行业的复苏前景在不同的城市
- 百事通!2022年安全生产月工作总结最新8篇
- 从“新”出发,用“心”护航!熟悉温馨的
- 2022年度中国内地上市券商Wind ESG评级
- 协议书模板(精选10篇)
- 浦江县20家企业获评省级“专精特新”企业
- 天天微头条丨芝麻菜的做法
- 当日快讯:中国人民保险集团:1月子公司
- 企业动员大会发言稿范文5篇
- 坤泰股份:2月16日在深交所上市 股票代
- 世界短讯!“出门在外,我就是你们的半个
- 少年闰土全文|环球热消息
- 炜冈科技:IPO网上中签号码共有6.42万个-
- QQ三国四象装备怎么做-天天微动态
- 天天速递!皇家枪手崔斯特稀有吗?_皇家火
- 每日观点:又到开学季,这些消防安全请查
- 网上银行的优缺点分别是什么
- 路由器密码忘记了应该怎么办
- Bacalao 速讯
- 网速设置限速怎么设置_设置网络限速的方
- 国庆节手抄报内容资料字少|每日报道
- 环球动态:苗湖书会_关于苗湖书会的简介
- 授权委托书(公民委托诉讼代理人用) 全
- 小学三年级《分数的初步认识》教案精选范
- 每日消息!旗天科技董秘回复:公司以数字
- 永城西汉梁王陵_关于永城西汉梁王陵介绍
- 内双眼皮如何画眼线
- 焦点信息:提高识毒意识 山东这个县禁毒
- 韩国三大电池制造商去年全球市占率下降,
- 每日看点!生物质锅炉跟燃煤锅炉对比优缺
- 何充直言不讳原文及赏析 全球速看料
- 龙江“春风”助力农民工返岗复工
- lauan 信息
- 天然砗磲的作用-观焦点
- 荣耀50手机耳机线怎么接_耳机线怎么接-环
- 属于确定型决策方法的模型很多教材中介绍
- 今日德莱尼猎人甩枪动作_德莱尼猎人 全
- ridit分析_每日消息
- 超高校级是什么梗
- 派林生物:3651.0590万股限售股2月13日上
- 快讯:美元/马来西亚林吉特:下一个上行
- 全球最新:空调买几级能效的好_空调几级
- 粤桂股份(000833)2月7日主力资金净买入
- 胸贴是什么呀 天天滚动
- 【焦点热闻】实力认证 领跑行业 东方通
- 天天观察:caxa教程怎么绘图_caxa教程
- 全球微头条丨一种柔性蠕动管道机器人机构
- dnf进入不了游戏_dnf为啥登录不了游戏_焦
- 企业动员大会发言稿范文5篇
- 坤泰股份:2月16日在深交所上市 股票代
- 世界短讯!“出门在外,我就是你们的半个
- 少年闰土全文|环球热消息
- 炜冈科技:IPO网上中签号码共有6.42万个-
- QQ三国四象装备怎么做-天天微动态
- 天天速递!皇家枪手崔斯特稀有吗?_皇家火
- 每日观点:又到开学季,这些消防安全请查
- 网上银行的优缺点分别是什么
- 路由器密码忘记了应该怎么办
- Bacalao 速讯
- 网速设置限速怎么设置_设置网络限速的方
- 国庆节手抄报内容资料字少|每日报道
- 环球动态:苗湖书会_关于苗湖书会的简介
- 授权委托书(公民委托诉讼代理人用) 全
- 小学三年级《分数的初步认识》教案精选范
- 每日消息!旗天科技董秘回复:公司以数字
- 永城西汉梁王陵_关于永城西汉梁王陵介绍
- 内双眼皮如何画眼线
- 焦点信息:提高识毒意识 山东这个县禁毒
- 韩国三大电池制造商去年全球市占率下降,
- 每日看点!生物质锅炉跟燃煤锅炉对比优缺
- 何充直言不讳原文及赏析 全球速看料
- 龙江“春风”助力农民工返岗复工
- lauan 信息
- 天然砗磲的作用-观焦点
- 荣耀50手机耳机线怎么接_耳机线怎么接-环
- 属于确定型决策方法的模型很多教材中介绍
- 今日德莱尼猎人甩枪动作_德莱尼猎人 全
- ridit分析_每日消息
- 超高校级是什么梗
- 派林生物:3651.0590万股限售股2月13日上
- 快讯:美元/马来西亚林吉特:下一个上行
- 全球最新:空调买几级能效的好_空调几级
- 粤桂股份(000833)2月7日主力资金净买入
- 胸贴是什么呀 天天滚动
- 【焦点热闻】实力认证 领跑行业 东方通
- 天天观察:caxa教程怎么绘图_caxa教程
- 全球微头条丨一种柔性蠕动管道机器人机构
- dnf进入不了游戏_dnf为啥登录不了游戏_焦
- 国家开放性大学与自考的区别_国家开放大
- 结算业务_关于结算业务介绍-世界观热点
- 欧文在休赛期可以与独行侠最高签5年2.72
- 消息!山东大学历山学院简介_山东大学历
- 泽连斯基发推:准备好援助_每日热门
- 天天资讯:林孝埈夺冠,国足又被打脸了!
- 头条:上海孚腾私募基金管理有限公司
- 【全球报资讯】2023年自贡灯会好久结束
- 农发行三台县支行贷款余额突破40亿元
- 威唐工业2月6日加速下跌 天天精选
- “中国天眼”发现的脉冲星已超740颗-天天
- 安公子·弱柳丝千缕-快资讯
- 日本,埋头印钞!妄图再度崛起,恢复昔日
- 一张图看懂充分必要条件_充分必要条件口
- 世界看点:格力渠道变革之痛还会持续多久
- 辅助生殖跑步进医保!千亿蓝海加速扩容,
- 木勺_环球热讯
- 龙头寺
- 温碧霞和赵雅芝都很懂装嫩,穿衣打扮是很
- 全球微动态丨两罚制