1.程序的翻译环境和执行环境
总体过程:
在ANSI C的任何一种实现中,存在两个不同的环境
第1种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。 第2种是执行环境,它用于实际执行代码。
2.翻译环境(编译+链接)
我们常说一个test.c文件要经过以下步骤才能产生可执行的程序,那么具体是怎么做到的呢?
在vs编译器上是要经过以下过程的:
源文件和目标文件的关系:
VS是一个集成开发环境,集成很多的功能ctr1+F5,不方便观察每个细节的功能接下来,我使用gcc这个编译器给大家演示
由于上图的操作把这个编译运行的步骤一次走完了,我们一步步来,咱们用指令让程序停在预编译的阶段:
编译(编译器)
预编译(预处理)
将控制台的内容放到test.i之后,预处理阶段所做的事情:
1.头文件的包含
2.注释的测试
编译过程
功能:把C语言代码翻译成汇编代码
经历四个过程:涉及一门课 -- 《编译原理》
1.语法分析 2.词法分析 3.语义分析 4.符号汇总 函数名,全局变量, 不会汇总 局部变量(函数运行起来才行)
编译阶段所做的事情,gcc操作过程:
汇编过程
1.把汇编代码转换成二进制的指令
2.形成符号表
链接
1.合并段表 2符号表的合并和重定位 1、2的作用其实是在链接期间为这种跨文件的代码进行协作的时候起作用的。
在vscode中操作:
过程:
1.合并段表
2.符号表的合并和重定位
把无效的地址给替换掉,符号表和段表的关系是:符号表是段表的内容
那该如何体现这个作用呢?
假设我们在test.c文件底下extern了一个函数Add,但是在add.c底下没有实现这个Add函数,就会输出以下错误(链接型错误)
如果说这个函数写错的话,在main函数内调用大写的,但是在add.c内定义成小写的,是依然找不到
计算机语言的发展
运行环境(翻译之后)
🔍程序执行的过程:
1. 程序必须载入 内存 中。在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。 2. 程序的执行便开始。接着便调用 main 函数(main函数第一行开始) 3. 开始执行程序代码。这个时候程序将使用一个运行时堆栈( stack )-- 函数栈帧 ,存储函数的局部变量和返回地址。 程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程一直保留他们的值。 4. 终止程序。正常终止 main 函数;也有可能是意外终止。
3.预处理详解
3.1 预定义符号
这些预定义符号都是语言内置的。
__FILE__ //进行编译的源文件 __LINE__ //文件当前的行号 __DATE__ //文件被编译的日期 __TIME__ //文件被编译的时间
执行:
这个预定义符号也是语言内置的
__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义
而放在gcc编译器上面是可以执行通过的:
编译器在代码编译的时候,会对函数和变量名重命名的,C++ 中会更加复杂
在C语言中重命名的规则基本就是:加_
【C进阶】C程序是怎么运作的呢?-- 程序环境和预处理(上)-2