作者:小 琛
欢迎转载,请标明出处。
程序编译的过程
一套代码,在写好执行的时候,其本身也是分好几个步骤的。在windows下使用vs编译看不到这样的过程,而我们假如使用Linux编译,其过程就可以清楚的看清。
预处理阶段
预处理完成之后就停下来,预处理之后产生的结果都放在test.i文件,在该阶段进行四项操作:
1、展开头文件。
2、宏替换。即我们在代码中所写的宏,真正执行的时候是使用替换法。
3、去注释。在编写代码的时候,为了使代码阅读性强,我们会加入一些注释,但这些注释对代码本身是没有作用的,因此在编译的时候会将其去掉
4、条件编译。这个与编写者本身有关
编译阶段
在该阶段主要进行代码语法的检查,如果编译通过,生成汇编代码,编译完成之后就停下来,结果保存在test.s中
汇编阶段
在该阶段将上一阶段生成的汇编代码转换为二进制的机器码,汇编完成之后就停下来,结果保存在test.o中
链接阶段
每个目标文件由链接器(linker)捆绑在一起,形成一个单一而完整的可执行程序。
再谈“宏”
在之前的学习中,我们在不少的地方都用到了宏,本博文就这个问题再深入学习
1、#define机制包括了一个规定,允许把参数替换到文本中。
例如:#define SQUARE(x) xx
在有了上述声明后,使用SQUARE(5)就相当于55。
但注意,该写法有着很大的漏洞
例如:SQUARE(5+1));第一眼看或许以为结果是36,但如果带入变成了:5+15+1,答案11。
#define是一个比较“笨”的员工,他只会按照要求搬运,因此在编写宏的时候一定要注意:在宏定义上加上括号,这个问题便轻松的解决了
SQUARE(x) ( (x)(x) )
因此:所以用于对数值表达式进行求值的宏定义都应该用这种方式加上括号,避免在使用宏时由于参数中的操作符或邻近操作符之间不可预料的相互作用。
2、宏函数
宏通常被应用于执行简单的运算,而使用宏不用函数,原因有这几点
(1)使用函数法需要在栈上单独开辟内存,因此需要更多的时间。
(2)函数的参数必须声明类型,而宏则不需要,它可以兼容所有的类型
3、宏的优点与缺点
优点:宏最重要的优点就是增强代码的复用性,其次因为宏函数的存在还有减少栈开销的效果
缺点:
(1)每次使用宏的时候,一份宏定义的代码将插入到程序中。除非宏比较短,否则可能大幅度增加程序的长度。
(2)宏是没法调试的。
(3)宏由于类型无关,也就不够严谨。
(4)宏可能会带来运算符优先级的问题,导致程容易出现错。
本博文到此结束,感谢浏览