C语言的程序环境和预处理指令

目录

程序环境

翻译环境

执行环境

预处理指令


程序环境

在ANSIC的任何一种实现中,存在两个不同的环境。

第1种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。

第2种是执行环境,它用于实际执行代码。

翻译环境

翻译环境又可以细分为:预编译(预处理)->编译->汇编->链接。

预编译、编译和汇编在编译器上执行,链接在连接器上执行。

编译器在翻译环境通过编译将源文件加工成可执行文件后,再交给执行环境进行执行操作。

C语言的程序环境和预处理指令_第1张图片

预编译阶段程序自动加载#include所包含的头文件中的内容 ,同时进行#define的符号替换和删除注释内容。

编译阶段将C语言代码转换成汇编代码,总共经过语法分析、词法分析、语义分析和符号汇总四个阶段。

汇编阶段将汇编代码转换成二进制指令并形成符号表。

链接阶段进行段表的合并即符号表的合并和重定位。

当我们进行多文件操作时,往往在不同的文件中都要引用某一个头文件或者使用某个我们自己创建的函数,而这个函数名就可以看作是一种符号,通过链接操作,可以避免函数的多次定义问题。同时函数是否已定义也是在链接阶段进行检查的。

执行环境

程序执行的过程:

1. 程序必须载入内存中。在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。

2. 程序的执行便开始。接着便调用main函数。

3. 开始执行程序代码。这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程一直保留他们的值。

4. 终止程序。正常终止main函数;也有可能是意外终止。

预处理指令

首先是某些预定义符号:

__FILE__ //进行编译的源文件
__LINE__ //文件当前的行号
__DATE__ //文件被编译的日期
__TIME__ //文件被编译的时间
__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义

可以直接将其打印出来:

C语言的程序环境和预处理指令_第2张图片

 接着是#define定义宏:

宏的声明方式:

#define name(parament-list) stuff

注意:

参数列表的左括号必须与name紧邻。

如果两者之间有任何空白存在,参数列表就会被解释为stuff的一部分。

宏的替换是发生在预编译阶段的,宏只是简单的替换,不能改变运算顺序,必要时需要加括号。

宏与函数的区别:

  • 因为宏只是简单的替换,不需要像函数那样,先开辟空间什么的再使用最后返回,因此宏的速度更快。
  • 宏对参数无要求,只要编译没有错误都可以执行,因此其包容性更强,有时可以完成函数所做不到的功能,不过也正因为这样的一个特性,宏在使用时要对操作符的优先级格外重视,否则可能造成不可预料的后果。
  • 宏没有递归操作,而函数可以递归。
  • 宏的替换操作无法通过调试观察,而函数可以洞悉每一步操作。

你可能感兴趣的:(c语言,c++,开发语言)