【C语言】预处理的深入理解_程序猿教你打篮球
人间骄阳刚好 风过林梢,彼时我们正当年少
目录
1、#define的深层次认识自己 1.1 计算结果宏常量? 1.2 空格符串宏常量? 1.3 用宏成为注解数字符号 1.4 用宏复制多行语句? 1.5 宏概念的在使用最好是 2、#undef 申请撤销宏 2.1 宏的构成地位和行之有效依据 2.2 宏的撤消? 2.3 一条面试题1、#define的深度认识
1.1 数值宏常量?
宏定义数值常量相信大家都不陌生,相信很多小伙伴用过,这里我们就简单的提一下,我们前面也讲过,#define 本质上是替换,它可以出现在代码的任何地方,也可以把任何东西都定义成宏,编译器会在预编译的时候进行替换掉,举例:
#dfeine PI 3.1415926
这样在以后的代码中你就可以用 PI 来代替 3.1415926 那么这样做的好处是什么呢?假设在未来的某一天,你要提升这个精度,如果你代码中出现 3.1415926 过多的话,你提升精度还得一个个修改, 如果使用宏定义的话,你只需要改一次即可。
1.2 字符串宏常量?
除去宏设定常量之下,还常用设定空数组,特点是绝对路径:① #define PATH_1 D:\code\lesson1\test
②?#define PATH_1 "D:\code\lesson1\test"
上文任何是规范的呢?假设都觉得太久还能够 用续行符:③ #define PATH_1 "D:\code\lesson1\\
test"
很很显然其次个毫无疑问可不对的,标识符串要有用 "" 吸引来,其5个是不对,其次个呢?咱们去实际 材料下(及以上写法全都不安利!):在Linux平台环境下:
在Windows环境下:?
很显然他们都有同样的警告,都是未知转义序列,也无法正确打印出我们的路径,在前面我们讲到,' \ ' 是转义字符,当我们要打印路径的时候需要用转义字符 ' \ ' 去还原 ' \ ' 的字面意思,所以这里打印路径要用 \\ !
注意:Windows路径分隔是用 ' \ ',而Linux路径分隔是用 ' / ',所以如上测试用例改成 ' / ' 的话是不会报警告的。
所有要规范的打印机如用例一般这样一来写://不使用续行符
#define PATH_1 "D:\\code\\lesson1\\test"
//使用续行符
#define PATH_1 "D:\\code\\lesson1\\\
test"
1.3 用宏充当注释符号
因 Linux 区域自然环境能立即手机查看预操作操作过程,有助我国核验,这些我国下方会在 Linux 区域自然环境下检查。 我先比较简单认知下源程序的英译时候:- 预处理-E:头文件展开,去注释,宏替换,条件编译...编译-S:将预处理后的C语言翻译成汇编语言汇编-c:将汇编语言转化为可目标二进制文件( 可被链接 )链接:将目标二进制文件与相关库链接,形成可执行程序
#include <stdio.h>
#define BSC //
int main()
{
BSC printf("hello world\n");
printf("you can see me!\n");
return 0;
}
这个我要探析其中个哪种话题呢?假如代替出色,则不是连接第其中个变量,假如代替验证失败,则我会看清楚两栏直接打印:
[lwp@localhost code]$ gcc -E test.c -o test.i?
把预处理后的结果保留下来为 test.i 文件,接着我们可以去用 vim 编辑器查看一下它与源文件的区别在哪,究竟是如何替换的:
通过上图我们可以发现,在预处理之后的文件中,并没有去成功通过宏替换注释掉第一个 printf 函数,由此可见,在预处理阶段,是先执行去掉注释,然后在进行宏替换,如上代码,本质是直接定义了一个空宏,我们特别不推荐这样写代码!(C语言注释风格也一样不行,感兴趣可以下去尝试下)
1.4 用宏替换多条语句?
看段编码:#include <stdio.h>
#define INIT_VALUE(a, b) a = 0; b = 0;
int main()
{
int flag = 0;
scanf("%d", &flag);
int a = 100;
int b = 200;
if (flag)
INIT_VALUE(a, b);
else
printf("%d, %d\n", a, b);
return 0;
}
你想问下,这些编号事情吗?须得怎么调整呢?这些编号看不出是编译不用能够 的,同时能否能够 进行预加工进行工作标志位,知道预加工进行工作并没了出事情,这么,我门能否看了解预加工进行工作在此之后的结局与源相关文件的差异去哪里:
- 去掉宏定义的最后一个分号规范代码风格,给 if 和 else 加上大括号给宏定义要替换的部分用大括号括起来
第一种解决方法肯定是不行的,去掉最后一个分号并不能解决问题,if else 在没有大括号的情况下后面只能跟一条语句,所以第一条行不通。
第三个种来解决措施其实较好,并且我国可有有想过,并不其他人都会有非常好的码音乐风格,我国有所作为应用码农,列举的宏都应该拥有壮实性,于是第三个条不能取。第三种解决方案我们看着好像靠谱,但是我们通常写完一条语句中后面都会带上分号,那可想而知会出现这种情况:{a = 0, b = 0;}; 大括号外是不能跟分号的,所以这个方法也不可取!
最好的解决方法是什么呢?使用 do while 结构:
#include <stdio.h>
#define INIT_VALUE(a, b) do{a = 0; b = 0;}while(0)
int main()
{
int flag = 0;
scanf("%d", &flag);
int a = 100;
int b = 200;
if (flag)
INIT_VALUE(a, b);
else
printf("%d, %d\n", a, b);
return 0;
}
循环会被看成一条复合语句,所以 if 不带大括号也没事(建议带上),这样我们的宏就会更健壮,也不会出错,同时你也可以在中间添加续行符,让他们的格式更清晰!同时我也有个小建议,宏定义的结尾最好都不要带分号。
结论: 当我们需要宏进行多条语句替换的时候,推荐使用 do-while-zero结构。
1.5 宏定义的使用建议
【意见和建议1】在宏构成体的结局省略分号。 【意见2】变量宏的启用不能少略因素。 【推荐3】函数值宏的表述中,一个参数指标都一般以小括号括起來,不要转换完后现身优先级的现象。2、#undef 撤销宏
2.1 宏的定义位置和有效范围
第一个问题,宏定义的位置有限制要求吗?
答案:源文件的任何地方,宏都可以定义,与是否在函数内外无关。
第二个问题,宏的有效范围有多大呢?
#include <stdio.h>
void test()
{
printf("test: %d\n", M);
}
int main()
{
test();
#define M 10
printf("main: %d\n", M);
return 0;
}
?这些二维码我们的都就出现 编译无法接通已过,那我们的都来入驻预补救系统文件下载来差别下源系统文件下载:
答案:宏的作用范围,从定义处开始,往后都是有效的!?
2.2 宏的取消?
此处自己用一种举例就能很好的的证明信了: #include <stdio.h>
2
3 #define M 10
4 int main()
5 {
6 printf("%d\n", M);
7 #undef M
8 printf("undef: %d\n", M);
9 return 0;
10 }
我们公司来观察如上二维码的预除理后续的报告单:
结论:undef 是取消宏的意思,可以用来限定宏的有效范围!?
2.3 一道笔试题
#include <stdio.h>
int main()
{
#define X 3
#define Y X*2
#undef X
#define X 2
int z = Y;
printf("%d\n", z);
return 0;
}
谁能告诉我男子伴们,这一段时间二维码word打印什么样的?
这个如果你不qq截图给许多人好看,感学习兴趣的还可以擅自落下去敲一敲,经过了Linux的渠道和windows的渠道的测试软件,终于打印机的是 4,鉴于编译器是以打到下扫锚码的,以最近的的宏的定义准确。
To shine, not be illuminated.
皇冠新体育APP相关的文章
- 当艺术遇上AI:AI赋能生产力的可能场景和应用思路_AITIME论道
- 皇冠新体育APP:编程常见的问题(二) 代码加锁_五音诗.
- [牛客社区开发(六)]集成Kafka消息队列_练习两年半的coder
- 皇冠新体育APP:8.Flink实时项目之CEP计算访客跳出_选手一号位
- 【ML笔记】5、支持向量机(SVM)_ingy
- 5.3 Kafka概述_炫云云
- 6-Kafka原理__小笼包__kafka背压机制
- 【我的Android进阶之旅】Android Studio的Dolphin版本的更新了Logcat,让您可以更轻松地解析、查询和跟踪日志!快跟着我实操一遍吧!_字节卷动
- 皇冠新体育APP:linux安装kafka(单节点启动)_java程序员-小程_单节点启动整个kafka集群
- Apache DolphinScheduler 获 CSDN IT 技术影响力之星评选「年度开源项目」_DolphinScheduler社区
- 皇冠新体育APP:干货 | 数字经济创新创业??软件研究_数据派THU
- 皇冠新体育APP:kafka 调整offset_G-S_kafka修改offset
- 皇冠新体育APP:GeoTools-WKT\GeoJson\Geometry相互转换_孙霸天_wkt转geojson
- 从vivo的创新方法论中,读懂高端突破的“因果”_脑极体
- 闯关_是七姑娘啊
- 皇冠新体育APP:Flutter JSON数据解析_xiangxiongfly915_flutter json