【C语言】程序的编译和链接(基础向)

程序的编译和链接

  • 1、翻译环境和运行环境
  • 2、翻译环境
  • 3、预处理(预编译)
    • 3.1编译
    • 3.2汇编
    • 3.3链接
    • 3.4GCC编译过程分解
  • 4、运行环境

1、翻译环境和运行环境

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

  1. 翻译环境:源代码--->可执行的机器指令(二进制指令)
  2. 执行环境:实际执行代码

这就是当我们写代码:

C 复制代码
#include<stdio.h>
int main()
{
	printf("hehe\n");
	return 0;
}

屏幕上会打印hehe的原理

2、翻译环境

翻译环境由编译链接 两大过程组成,而编译 又可以分解成:预处理、编译、汇编三大过程。

一个C语言的项目可以由多个.C文件组成,下面是组成的原理

  • 多个.C文件单独经过编译器,编译处理生成对应的目标文件

  • Windows环境下的目标文件的后缀是.obj,Linux环境下目标文件的后缀是.o

  • 多个目标文件和链接库一起经过链接器处理生成最终的可执行程序

  • 链接库是指运行时库或第三方库

把编译器再展开3个过程,那就变成了下面图:

执行顺序:C代码 --- 预处理 --- 编译 --- 汇编 --- 链接 --- 可执行程序

3、预处理(预编译)

在预处理阶段,源文件和头文件会被处理成为.i为后缀的文件

gcc环境下想观察对test.c文件预处理后的.i文件,命令为:

复制代码
gxx -E test.c -o test.i

预处理阶段主要处理那些源文件中#开始的预编译指令。比如:#include,#define,处理的规则如下:

  • 将所有的#include预编译指令,如:#if、#ifdef、#dlif、#else、#endif
  • 处理#include预编译指令,将包含的头文件的内容插入到该预编译指令的位置。这个过程时递归进行的,也就是说被包含的头文件也可能包含其他文件
  • 删除所有的注释
  • 添加行号和文件名标识,方便后续编译器生成调试信息等
  • 保留所有的#pragma的编译器指令,编译器后续会使用
    经过预处理后的.i文件中不再包含宏定义,因为宏已经被展开。并且包含的头文件都被插入到.i文件中。所以当我们无法知道宏定义或者头文件是否包含正确的时候,可以查看预处理后的.i文件来确认。

3.1编译

编译过程就是将预处理后的文件进行一系列的:词法分析、语法分析、语义分析及优化 ,生成相应的汇编代码文件

编译过程的命令:
gcc -S test.i -o test.s

如果对下面代码
array[index] = (index + 4)*(2 + 6)

编译时,编译器会怎么做呢?

根据记号,会生成下列的语法树

3.2汇编

汇编器 时将汇编代码转变成技巧可执行的指令

汇编命令如下:
gcc -c test.s -o test.o

3.3链接

当有两个甚至多个.c文件时,编译器是先把每个函数的链接合并到一起,然后再使用,如下图中的加法函数:

![[QQ20251019-111103.png]]

3.4GCC编译过程分解

复制代码
// 分布执行,观察每个阶段的输出
gcc -E test.c //只预处理
gcc -S test.c //生成汇编代码
gcc -c test.c //生成目标文件
gcc test.o    //链接生成可执行文件

4、运行环境

  1. 程序必须载入内存中。在有操作系统的环境中:⼀般这个由操作系统完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。
  2. 程序的执行便开始。接着便调用main函数。
  3. 开始执行程序代码。这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程⼀直保留他们的值。
  4. 终止程序。正常终止main函数;也有可能是意外终止。
相关推荐
⑩-2 小时前
SpringCloud-Nacos 配置中心实战
后端·spring·spring cloud
charlie1145141913 小时前
现代嵌入式C++教程:C++98——从C向C++的演化(2)
c语言·开发语言·c++·学习·嵌入式·教程·现代c++
雨季余静3 小时前
c语言 gb2312转utf-8,带码表,直接使用。
c语言·c语言utf8·c语言gb2312·c语言gbk·c语言gb18030·gb2312转utf8·gbk转utf8
2401_890443023 小时前
Linux 基础IO
linux·c语言
java1234_小锋3 小时前
[免费]SpringBoot+Vue勤工助学管理系统【论文+源码+SQL脚本】
spring boot·后端·mybatis·勤工助学
踏浪无痕4 小时前
从 Guava ListenableFuture 学习生产级并发调用实践
后端·面试·架构
❀͜͡傀儡师4 小时前
SpringBoot 扫码登录全流程:UUID 生成、状态轮询、授权回调详解
java·spring boot·后端
可观测性用观测云4 小时前
观测云在企业应用性能故障分析场景中的最佳实践
后端
一 乐5 小时前
酒店预约|基于springboot + vue酒店预约系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端