【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函数;也有可能是意外终止。
相关推荐
Victor3569 小时前
https://editor.csdn.net/md/?articleId=139321571&spm=1011.2415.3001.9698
后端
Victor3569 小时前
Hibernate(89)如何在压力测试中使用Hibernate?
后端
灰子学技术11 小时前
go response.Body.close()导致连接异常处理
开发语言·后端·golang
Gogo81612 小时前
BigInt 与 Number 的爱恨情仇,为何大佬都劝你“能用 Number 就别用 BigInt”?
后端
fuquxiaoguang12 小时前
深入浅出:使用MDC构建SpringBoot全链路请求追踪系统
java·spring boot·后端·调用链分析
毕设源码_廖学姐13 小时前
计算机毕业设计springboot招聘系统网站 基于SpringBoot的在线人才对接平台 SpringBoot驱动的智能求职与招聘服务网
spring boot·后端·课程设计
野犬寒鸦14 小时前
从零起步学习并发编程 || 第六章:ReentrantLock与synchronized 的辨析及运用
java·服务器·数据库·后端·学习·算法
逍遥德15 小时前
如何学编程之01.理论篇.如何通过阅读代码来提高自己的编程能力?
前端·后端·程序人生·重构·软件构建·代码规范
wangjialelele15 小时前
平衡二叉搜索树:AVL树和红黑树
java·c语言·开发语言·数据结构·c++·算法·深度优先
森G15 小时前
七、04ledc-sdk--------makefile有变化
linux·c语言·arm开发·c++·ubuntu