预处理章节总结(干货满满)

fdf6b70c44ed684c!400x400

要么做第一个,要么做最好的一个。


1:程序的翻译环境🍔

image-20220719221326390

  • 组成程序的每个源文件通过编译器转换为目标代码
  • 每个目标文件链接器捆绑在一起,形成一个个单一可执行的程序。
  • 链接器同时会进入C函数库中寻找被该程序所用到的函数,并且可以搜索程序员个人的程序库(如个人编写的函数项目),将其需要的函数引用到该程序中。

2:编译环节详解🍟

2:1预编译环节🌭

  • 预编译环节会将define定义的标识符替换

  • 然后将define定义的标识符在预编译环节删除,此时会生成##.i的文件

  • 注释的删除,因为在##.i文件中是看不见注释的,注释留给程序员自己观察

    也就是文本操作

2:2编译环节🥐

  • 此时文件生成了##.i的文件,开始进行语法分析
  • 词法分析
  • 符号汇总
  • 语义分析

2:3汇编环节🍳

  • 汇编代码转化为二进制指令

  • 形成符号表,也就是将各个文件下的函数分别地址合并形成表格

2:4链接环节🥩

  • 在汇总环节中已经将符号汇总存放至表格中,那么在链接环节会合并所有符号表
  • 符号表的重定位

3:多次声明的后果🥪

image-20220719225010051

会在汇编过程中,多次重复同一条符号的符号表,从而降低程序运行效率

4:预处理讲解🍖

4:1define定义宏🍗

4:1:1define定义宏的格式注意🍩

#define DIV(x,y) x*y
int main()
{
printf("%d",DIV(2+3,4+5);
return 0;
}

运行结果为19

原因:宏是一个替换的过程,所以在替换的时候,只是把x变为2+3,y变为4+5, x*y == 2+3 * 4+5;

因此我们在定义宏的时候就要注意到对参数进行括号处理

#define ADD (x)+(y)
#define MUL (x)-(y)
#define DIV (x)*(y)

仔细观察ADD这一条宏语句,我们如果对参数进行括号处理难道就已经足够了吗?

#define ADD (x)+(y)
int main()
{
int x = 10*DIV(3+2,4+5);
return 0;
}

同样的(x)(y) == 3+2+4+5;如果没有14,结果应该是,但是 *10处理后是什么样子情况呢?

10*(3+2)+(4+5) == 10*5+9 = 59

这里其实程序员本身想法是想获得10*ADD的结果,却发生了部分相乘,因此我们在定义宏的时候不仅需要对参数括号处理,对整条宏语句应该进行括号处理。

4:1:2define定义宏时#的运用🥡

printf("hello""baby");

这条语句打印结果应该是hellobaby,因此我们在打印函数中使用多个字符串是可以的

int main()
{ int a = 0;
  int b = 0;
printf("the value of a is %d",a);
printf("the value of b is %d",b);
//可以看到这里想要打印2个字母的值,后半部分是可以的,但是前面of # 这里,如果使用函数是无法实现的,因此只能使用宏
}
#define PRINT(a) (printf("the value of # is %d",a))

那么这个时候可以用到开头相同的语法,把#对应的内容转化为字符串如下

#define PRINT(a) (printf("the value of "a" is %d",a))

然而此时还不行,因为宏是一个替换过程,如果a=10,那么此时仍会把“a”变为“10”,因此就需要运用到#变为如下

#define PRINT(a) (printf("the value of "#a" is %d",a))

此时便可以成功打印出以下内容

image-20220719233627031

4:1:3define定义宏时##的运用🥫

作用是将位于两边的符号合成一个符号

#define SUM(a,value)
int main()
{SUM(5,10);
return 0;}

SUM宏把a和value合并,a被替换为5,那么这条宏就是把SUM5+10的作用。

4:2带副作用的宏参数🍜

#define MAX(a,b) ((a++)<(b++)?:(a) : (b))
int main()
{
 int m = MAX(5,4);
}

问:程序结束后a,b,m的值是多少

答:a=6;b=5;m=7;

//这条宏语句是比较大小,(5++)<(4++)?(6++):(5++);
//过程中有副作用,就是在比较大小后a的替换内容变成了6++,b的替换内容变成了5++,因此返回值是返回6++也就是7

因此,在写这种代码的时候,建议把a++和b++更改为a+1和b+1,避免副作用发生。

4:3避免头文件多次包含的方法🍝

ifundef __TEST.H__
#define __TEST.H__
#endif 

或者

#pragma once

5:博客结尾🍹

经过几个月的努力,博主C语言内容已经接近尾声,但是!作为在程序员的道路上才刚刚启航。博主决定另创新号发布数据结构以及c++的知识点分享,各位粉丝uu们,生活尚不美好,钱包尚空,我们仍需努力!✌

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不熬夜不抽烟不喝酒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值