【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函数;也有可能是意外终止。
相关推荐
梅小西爱学习3 小时前
线上CPU飙到100%?别慌,这3个工具比top快10倍!
java·后端·cpu
radient3 小时前
属于Agent的课本 - RAG
人工智能·后端·程序员
第七序章3 小时前
【C + +】红黑树:全面剖析与深度学习
c语言·开发语言·数据结构·c++·人工智能
程序员阿达3 小时前
开题报告之基于SpringBoot框架的路面故障信息上报系统设计与实现
java·spring boot·后端
用户3421674905523 小时前
鱼皮模拟面试,吊打面试官
后端
我是天龙_绍4 小时前
java 中的 Lombok
后端
hwangsy4 小时前
SpringCloud gateway偶发creationTime key must not be null
后端
初见0014 小时前
Spring事务失效的十大陷阱与终极解决方案
后端·架构
子夜master4 小时前
玩转EasyExcel,看这一篇就够了!!(合并导入 自定义导出 动态表头 合并单元格)
后端