C语言程序环境和预处理

来源:互联网 发布:灰鸽子远程控制源码 编辑:程序博客网 时间:2024/05/17 21:58

我们在写完代码后需要对代码进行编译和执行,点完按钮后编译器就自动生成了结果,难道小伙伴们不好奇编译执行过程中发生了什么事情吗?今天就来写一下程序环境和预处理。
C语言程序环境
翻译环境和执行环境
翻译环境是将源程序代码翻译成机器所能识别的二进令;
 执行环境是执行已经翻译好的代码。
翻译环境:程序中的各个源代码通过编译器形成目标文件,每个目标文件在链接器中集合,链接器可以引入标准c语言库中的函数以及程序员自己的函数库,将其需要的函数链接到程序中形成可执行程序。
这里写图片描述
上述定义在提到的编译器对源代码进行编译,可分为以下三个阶段:
预处理:(文本操作)
头文件的包含;注释的删除;#define标识符的替换和删除;宏定义的替换,最后生成test.i文件。
编译:
生成汇编代码;语义分析;语法分析;符合汇总,最后生成test.s文件。
汇编:
将汇编代码转化成二进制代码,最后生成test.o文件。
链接器对目标文件进行链接:进行符号表的合并,重定位;合并段表,最后生成test.exe文件。
执行环境:先手动或者在有操作系统的情况下将程序载入内存中;接下来通过程序入口函数main函数对程序进行执行;执行过程中程序将使用运行时堆栈存储局部变量或者函数中的局部变量以及返回地址,静态内存存储静态变量直到程序执行完销毁;最后终止main函数,程序执行结束。
预处理
首先介绍一下预定义符号
FILE LINE(确认调试输出的来源)
DATE TIME(可以加入版本信息)
STDC(只有在编译器遵循ANSI C 时才用,有效时值为1)

#define定义的标识符#define MAX 100#define DO_FOREVER  break;case //不再后面加;#define定义的宏#define MAX(x,y) ((x)>(y)?(x)(y)) //宏定义的参数要带括号#define SQ(x) ((x)*(x)) //整个宏定义的两边都要加上括号

介绍一下‘#’‘##’在宏这里的用法:
‘#’可以将宏参数转化成一个字符串。
#define PRINT(x)\
printf("the value of "#x" is %d",x)
int main()
{
      int b=10;
     PRINT(b);
}
输出结果:the value of x is 10

‘##’可以将前后字符连接成一个字符。

#include<stdio.h>#define SQL(x,y) ((x)##(y))int main(){     int tmp3=6;     int ret=SQL(tmp,3);     printf("%d",ret);}输出结果:6                  

相比于函数来说宏也可以进行简单的计算,现在来比较一下宏和函数:
宏代码在每次程序需要的地方都要被调用,小一点的宏代码还有用,但是当代码量大的时候就不适合了,然而函数只出现在一个地方,需要的时候调用即可;

宏参数可能还会导致副作用,#define MAX(x,y) ((x)>(y)?(x):(y))当参数是MAX(a++,b++)时,程序执行完之后a,b的值会发生变化,但是在函数中多次使用的参数不会导致副作用,在函数调用前只求值一次;

宏的执行速度较函数快,函数有调用和返回的开销;

宏参数无类型而言,函数的参数要定义类型;

宏命名的时候全大写英文,函数命名时部分英文。

原创粉丝点击