栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

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

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

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


文章目录
  • 1:程序的翻译环境
  • 2:编译环节详解
    • 2:1预编译环节
    • 2:2编译环节縷
    • 2:3汇编环节
    • 2:4链接环节數
  • 3:多次声明的后果索
  • 4:预处理讲解
    • 4:1define定义宏
      • 4:1:1define定义宏的格式注意
      • 4:1:2define定义宏时#的运用率
      • 4:1:3define定义宏时##的运用參
    • 4:2带副作用的宏参数
    • 4:3避免头文件多次包含的方法
  • 5:博客结尾

1:程序的翻译环境

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

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

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

    也就是文本操作

2:2编译环节縷
  • 此时文件生成了##.i的文件,开始进行语法分析
  • 词法分析
  • 符号汇总
  • 语义分析
2:3汇编环节
  • 把汇编代码转化为二进制指令

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

2:4链接环节數
  • 在汇总环节中已经将符号汇总存放至表格中,那么在链接环节会合并所有符号表
  • 符号表的重定位
3:多次声明的后果索

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

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))

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

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们,生活尚不美好,钱包尚空,我们仍需努力!✌

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1018030.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号