【C语言】编译与链接过程
文章目录一、程序的两种环境二、翻译环境2.1 多文件项目的构建流程2.2 编译的三个步骤2.2.1 预处理预编译2.2.2 编译2.2.3 汇编2.3 链接三、运行环境一、程序的两种环境在ANSI C的任何一种实现中都存在两个不同的环境它们共同支撑着C语言程序的生命周期。翻译环境这是源代码被转换为可执行的机器指令二进制指令的地方。我们编写的.c源文件就是在这个环境中经历一系列处理最终变成能被计算机识别的二进制代码。执行环境顾名思义它是用于实际执行代码的环境。当翻译环境生成可执行程序后就会在执行环境中运行产生我们需要的结果。举个简单的例子假设有test1.c、test2.c、test3.c三个源文件它们会先在翻译环境中经过编译、链接等过程生成可执行程序然后这个可执行程序在运行环境中输出结果。二、翻译环境翻译环境的核心任务是将源代码转换为可执行的机器指令它由编译和链接两个大的过程组成而编译又可以进一步分解为预处理预编译、编译、汇编三个步骤。2.1 多文件项目的构建流程一个C语言项目往往包含多个.c文件这些文件共同协作才能完成特定的功能。那么多个.c文件是如何一步步生成可执行程序的呢多个.c文件会单独经过编译器的处理生成对应的目标文件。这里需要注意的是在Windows环境下目标文件的后缀是.obj而在Linux环境下目标文件的后缀是.o。这些多个目标文件和链接库一起经过链接器的处理最终生成可执行程序。链接库指的是运行时库支持程序运行的基本函数集合或者第三方库。比如test.c经过编译器处理生成test.objadd.c经过编译器处理生成add.obj然后这些.obj文件与链接库在链接器的作用下生成可执行程序。Windows 环境下Linux环境下2.2 编译的三个步骤如果我们把编译器的工作展开会得到更细致的三个过程2.2.1 预处理预编译预处理阶段源文件.c为后缀和头文件.h为后缀会被处理成为以.i为后缀的中间文件。在gcc环境下我们可以使用如下命令观察对test.c文件预处理后的.i文件gcc -E test.c -o test.i预处理阶段主要处理源文件中以#开始的预编译指令具体规则如下将所有的#define删除并展开所有的宏定义。处理所有的条件编译指令如#if、#ifdef、#elif、#else、#endif。处理#include预编译指令将包含的头文件的内容插入到该预编译指令的位置。这个过程是递归进行的也就是说被包含的头文件也可能包含其他文件。删除所有的注释。添加行号和文件名标识方便后续编译器生成调试信息等。保留所有的#pragma的编译器指令供编译器后续使用。经过预处理后的.i文件中不再包含宏定义因为宏已经被展开并且包含的头文件都被插入到.i文件中。所以当我们不确定宏定义或者头文件是否包含正确时可以查看预处理后的.i文件来确认。2.2.2 编译编译过程是将预处理后的.i文件进行一系列的词法分析、语法分析、语义分析及优化最终生成相应的汇编代码文件.s为后缀。在gcc环境下编译过程的命令如下gcc -S test.i -o test.s我们以一段简单的代码array[index] (index4)*(26);为例来看看编译过程具体做了什么。词法分析源代码程序被输入扫描器扫描器会把代码中的字符分割成一系列的记号这些记号包括关键字、标识符、字面量、特殊字符等。上面的程序经过词法分析后会得到16个记号比如array标识符、[左方括号、index标识符、]右方括号、赋值等。语法分析语法分析器会对扫描产生的记号进行语法分析从而产生语法树。这些语法树是以表达式为节点的树。对于上面的代码会生成以赋值表达式为根节点下标表达式和乘法表达式为子节点的语法树下标表达式又包含array标识符和index标识符乘法表达式则由两个加法表达式组成等。语义分析语义分析器完成语义分析即对表达式的语法层面进行分析。编译器所能做的是语义的静态分析通常包括声明和类型的匹配、类型的转换等。这个阶段会报告错误的语法信息。比如在上面的代码中会对每个标识符和表达式进行类型标识确认array是整型数组index是整型各个表达式的结果也是整型等。经过这些步骤后就会生成汇编代码文件。2.2.3 汇编汇编器的作用是将汇编代码.s为后缀转变为机器可执行的指令目标文件.o或.obj为后缀。每一个汇编语句几乎都对应一条机器指令汇编过程就是根据汇编指令和机器指令的对照表一一进行翻译不做指令优化。在gcc环境下汇编的命令如下gcc -c test.s -o test.o2.3 链接链接是一个复杂的过程它需要把多个目标文件和链接库链接在一起最终生成可执行程序。链接过程主要包括地址和空间分配、符号决议和重定位等步骤其解决的是一个项目中多文件、多模块之间互相调用的问题。我们以一个具体的例子来理解链接的作用。假设有test.c和add.c两个.c文件test.c中的代码如下#includestdio.h// 声明外部函数externintAdd(intx,inty);// 声明外部的全局变量externintg_val;intmain(){inta10;intb20;intsumAdd(a,b);printf(%d\n,sum);printf(g_val%d\n,g_val);return0;}add.c中的代码如下intg_val2022;intAdd(intx,inty){returnxy;}我们知道每个源文件都会单独经过编译器处理生成对应的目标文件即test.c生成test.oadd.c生成add.o。在test.c中我们使用了add.c中的Add函数和g_val变量。但在编译器编译test.c的时候它并不知道Add函数和g_val变量的地址所以会暂时把调用Add的指令的目标地址和g_val的地址搁置。直到最后链接的时候链接器会根据引用的符号Add在其他模块这里就是add.o中查找Add函数的地址然后将test.c中所有引用到Add的指令重新修正让它们的目标地址为真正的Add函数的地址对于全局变量g_val也是用类似的方法来修正地址。这个地址修正的过程就被叫做重定位。三、运行环境当可执行程序生成后就会进入运行环境执行。程序的运行过程大致如下程序载入内存在有操作系统的环境中一般由操作系统完成程序的载入在独立的环境中程序的载入必须由手工安排也可能是通过可执行代码置入只读内存来完成。开始执行程序程序执行便开始接着会调用main函数。执行程序代码此时程序将使用一个运行时堆栈stack存储函数的局部变量和返回地址。同时程序也可以使用静态static内存存储于静态内存中的变量在程序的整个执行过程中一直保留它们的值。程序终止程序可能正常终止于main函数也可能意外终止。

相关新闻

windows错误解决方案大全(不定期更新)

windows错误解决方案大全(不定期更新)

一、0x8007007ewindows更新错误winr→downlevel→回车→确认大多数文件修改日期(比如我的是2024/4/1 15:22)→移出/删除修改日期不是上述日期(2024/4/1 15:22)的→安装更新

2026/8/4 12:39:47 阅读更多 →
浏览器里同时跑 99 个 AI 和 2100+ 粒子:WebGL2、Canvas 与固定时间步优化实战

浏览器里同时跑 99 个 AI 和 2100+ 粒子:WebGL2、Canvas 与固定时间步优化实战

我在做《星团大作战》时,遇到的性能问题并不是"Canvas 能不能画几个圆",而是下面这些工作会同时出现: 1 名玩家和 99 个 AI 持续移动、追击、逃跑、分裂与吞噬;76007600 的世界里,基础食物对象有 2100 个&a…

2026/8/6 14:54:01 阅读更多 →
终极指南:Photoshop图层批量导出插件如何将工作效率提升5倍

终极指南:Photoshop图层批量导出插件如何将工作效率提升5倍

终极指南:Photoshop图层批量导出插件如何将工作效率提升5倍 【免费下载链接】Photoshop-Export-Layers-to-Files-Fast This script allows you to export your layers as individual files at a speed much faster than the built-in script from Adobe. 项目地址…

2026/8/5 23:43:36 阅读更多 →

最新新闻

嵌入式总线技术全解析:从并行串行到单双工,实战选型与调试指南

嵌入式总线技术全解析:从并行串行到单双工,实战选型与调试指南

1. 从“路”到“总线”:为什么我们需要理解这些基础概念?如果你刚开始接触嵌入式开发、计算机组成原理,或者正在调试一个串口通信问题,看到“并行总线”、“串行总线”、“单工”、“全双工”这些词,是不是感觉既熟悉又…

2026/8/7 7:46:28 阅读更多 →
操作系统调度算法:SJF与RR的核心原理、性能对比与工程实践

操作系统调度算法:SJF与RR的核心原理、性能对比与工程实践

1. 从“谁先来谁先走”到“谁短谁先走”:调度算法的现实困境 在计算机操作系统的世界里,进程调度器就像一位交通警察,指挥着CPU这条繁忙的“单行道”上无数等待执行的“车辆”(进程)。我们最直观、最朴素的调度规则&am…

2026/8/7 7:46:28 阅读更多 →
SQL DELETE操作全解析:从基础语法到企业级实践

SQL DELETE操作全解析:从基础语法到企业级实践

1. SQL Delete操作基础解析SQL中的DELETE语句是数据库操作中最基础却最危险的命令之一。记得刚入行时,我曾在测试环境误删了整个用户表,导致团队不得不从备份恢复——这段经历让我深刻理解了DELETE操作需要慎之又慎。DELETE语句的核心功能是从数据库表中…

2026/8/7 7:46:28 阅读更多 →
C/C++中按位取反(~)与逻辑取反(!)的深度解析与应用

C/C++中按位取反(~)与逻辑取反(!)的深度解析与应用

1. 项目概述:从“取反”这个简单操作说起 在C和C的世界里,我们每天都在和各种操作符打交道, 、 - 、 * 、 / 这些算术操作符自不必说,但有两个符号, ~ 和 ! ,它们都叫“取反”,却常…

2026/8/7 7:46:28 阅读更多 →
C#零分配内存管理:Span与Memory实战指南

C#零分配内存管理:Span与Memory实战指南

1. 为什么C#开发者需要关注零分配内存管理 在C#开发中,GC(垃圾回收)虽然帮我们自动管理内存,但这种便利是有代价的。我在处理一个高频交易系统时,发现GC导致的性能波动让延迟指标始终无法达标。通过性能分析工具&#…

2026/8/7 7:46:28 阅读更多 →
Unity RuntimeInspector性能优化:从卡顿到流畅的架构与实战

Unity RuntimeInspector性能优化:从卡顿到流畅的架构与实战

1. 项目概述:当RuntimeInspector遇上性能瓶颈在Unity编辑器里拖拖拽拽,看着Inspector面板实时变化,是每个开发者都习以为常的场景。但当我们把这种“上帝视角”的能力带到运行时,特别是面对成百上千个动态生成的游戏对象时&#x…

2026/8/7 7:45:28 阅读更多 →

日新闻

为什么scrcpy成为Android投屏的终极解决方案:完整实战指南

为什么scrcpy成为Android投屏的终极解决方案:完整实战指南

为什么scrcpy成为Android投屏的终极解决方案:完整实战指南 【免费下载链接】scrcpy Display and control your Android device 项目地址: https://gitcode.com/GitHub_Trending/sc/scrcpy 想要将Android手机屏幕完美投射到电脑上,享受大屏操作的自…

2026/8/7 0:00:19 阅读更多 →
如何在5分钟内掌握Tom Select:打造现代化表单选择器的终极指南

如何在5分钟内掌握Tom Select:打造现代化表单选择器的终极指南

如何在5分钟内掌握Tom Select:打造现代化表单选择器的终极指南 【免费下载链接】tom-select Tom Select is a lightweight (~16kb gzipped) hybrid of a textbox and select box. Forked from selectize.js to provide a framework agnostic autocomplete widget wi…

2026/8/7 0:00:19 阅读更多 →
5分钟快速上手:NSZ压缩工具终极指南,轻松管理Switch游戏文件

5分钟快速上手:NSZ压缩工具终极指南,轻松管理Switch游戏文件

5分钟快速上手:NSZ压缩工具终极指南,轻松管理Switch游戏文件 【免费下载链接】nsz NSZ - Homebrew compatible NSP/XCI compressor/decompressor 项目地址: https://gitcode.com/gh_mirrors/ns/nsz 你是否在为Nintendo Switch游戏文件占用大量存储…

2026/8/7 0:00:19 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/6 22:02:27 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/6 22:02:27 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/6 22:02:27 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/5 23:28:39 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/6 22:02:28 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/5 23:46:51 阅读更多 →