深入理解 C 语言程序的编译与链接过程

DeepSeek助力学术审稿:高效处理审稿意见的实用提示词指南 本文介绍如何利用DeepSeek AI工具高效处理学术审稿意见,提供实用的提示词指南。从评审意见结构化整理到争议问题回应策略,详细解析AI在加速审稿流程中的应用技巧,帮助研究者大幅提升回复效率和质量。 阅读详情

在 C 语言的世界里,我们编写的源代码最终如何变成能在计算机上运行的程序?这背后离不开编译和链接的神奇魔法。今天,我们就来详细拆解这个过程,带你一探究竟。

一、程序的两种环境

ANSI C 标准定义了 C 语言实现的两种关键环境:

  • 翻译环境:负责将我们编写的源代码转换为计算机可执行的机器指令(二进制指令)。
  • 执行环境:用于实际运行生成的可执行程序,输出最终结果。

简单来说,翻译环境就像一位 "翻译官",把人类能看懂的 C 语言代码翻译成机器能理解的二进制语言;而执行环境则像一个 "舞台",让翻译后的程序在上面 "表演"。

二、翻译环境的工作流程

翻译环境的工作可分为编译和链接两大过程,其中编译又细分为预处理、编译和汇编三个步骤。对于一个包含多个源文件(如 test1.c、test2.c、test3.c)的项目,其处理流程如下:

  1. 每个.c 文件单独经过编译器处理,生成对应的目标文件
  2. 所有目标文件和链接库经过链接器处理,最终生成可执行程序

不同系统下的目标文件后缀

  • Windows 环境:.obj
  • Linux 环境:.o

三、编译的三个阶段

3.1 预处理(预编译)

预处理阶段会将源文件(.c)和头文件(.h)处理成以.i 为后缀的中间文件。在 gcc 环境下,可使用以下命令查看预处理结果:

gcc -E test.c -o test.i

预处理的主要工作包括:

  • 删除所有#define并展开所有宏定义
  • 处理条件编译指令(#if、#ifdef、#elif、#else、#endif)
  • 处理#include指令,将头文件内容插入到指令位置(该过程是递归的)
  • 删除所有注释
  • 添加行号和文件名标识,方便后续调试
  • 保留#pragma等编译器指令

预处理后的.i 文件已经展开了所有宏,插入了所有头文件内容,非常适合用来检查宏定义或头文件包含是否正确。

3.2 编译

编译阶段将预处理后的.i 文件通过词法分析、语法分析、语义分析及优化,生成汇编代码文件(.s)。在 gcc 中使用以下命令:

gcc -S test.i -o test.s

我们以array[index] = (index+4)*(2+6);为例,看看编译过程的具体操作:

  • 词法分析:将代码分割成一系列记号(关键字、标识符、字面量、特殊字符等),上述代码会被拆分为 16 个记号,如array(标识符)、[(左方括号)、index(标识符)等。
  • 语法分析:将记号组成语法树,表达代码的语法结构。
  • 语义分析:对语法树进行语义检查,如类型匹配等,并在语法树中添加类型信息。
  • 优化:对代码进行优化处理,生成更高效的汇编代码。

3.3 汇编

汇编阶段将汇编代码文件(.s)转换为机器可执行的指令,生成目标文件(.o 或.obj)。在 gcc 中使用以下命令:

gcc -c test.s -o test.o

汇编过程相对直接,每一条汇编语句几乎都对应一条机器指令,汇编器会根据汇编指令和机器指令的对照表进行一一翻译,不进行指令优化。 

四、链接

链接是将多个目标文件和链接库组合成可执行程序的过程,主要包括地址和空间分配、符号决议和重定位等步骤。

链接解决了多文件、多模块之间的相互调用问题。例如,在 test.c 中调用 add.c 中定义的函数或变量时:

  • 编译 test.c 时,编译器并不知道被调用函数或变量的实际地址,会暂时搁置
  • 链接阶段,链接器会查找这些符号的实际地址,并修正所有引用,这个过程称为 "重定位"

五、程序的运行环境

当可执行程序生成后,就进入了运行环境:

  1. 程序载入内存:通常由操作系统完成,独立环境中可能需要手工安排
  2. 开始执行:调用 main 函数作为程序入口
  3. 代码执行:
    • 使用运行时堆栈(stack)存储局部变量和返回地址
    • 使用静态(static)内存存储静态变量,其值在整个程序执行期间保持不变
  4. 程序终止:正常终止 main 函数,或意外终止

总结

C 语言程序从源代码到可执行程序的过程看似复杂,实则是一系列有序的转换:预处理处理宏和头文件,编译将代码转换为汇编语言,汇编生成机器指令,链接将多个模块组合成可执行程序。理解这个过程,有助于我们更好地调试和优化程序。

如果想深入了解更多细节,推荐阅读《程序员的自我修养》一书,它会带你探索目标文件格式、链接的底层实现等更深层次的知识。

multisim14.3无法访问数据库...如何解决? 🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。 阅读详情

相关推荐

基于单片机红外线遥控Proteus仿真电路发射接收

*单片机设计介绍,基于单片机红外线遥控Proteus仿真电路发射接收。

2201_75940997的博客 3943

【C语言】编译与链接:深入理解程序构建过程

本篇将深入理解程序构建过程,以便于我们在编写程序的过程同时,理解底层是如何从程序的创建到生成可执行程序的。

专注于 C/C++ 后端开发,涵盖基础语法、Linux系统与网络、MySQL数据库、常见算法及项目经验。 2593

BGE(BAAI General Embedding)模型详解

BGE(BAAI General Embedding)是北京智源人工智能研究院(BAAI)推出的通用文本嵌入模型系列,旨在为各种自然语言处理任务提供高质量的向量表示。

ttyy1112的专栏 7558

“预编译、编译、汇编、链接”四个过程

C语言的编译链接过程要把我们编写的一个c程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接。编译就是把文本形式源代码翻译为机器语言形式的目标文件的过程。链接是把目标文件、操作系统的启动代码和用到的库文件进行组织形成最终生成可执行代码的过程 从图上可以看到,整个代码的编译过程分为编译和链接两个过程,编译对应图中的大括号括起的部分,其余则为链接过程。 过程图解如下: 编...

lyw851230的专栏 1220

ESP32 TWAI CAN库实战:从零构建CyberGear微电机控制框架

本文详细介绍了如何利用ESP32的TWAI控制器和Arduino环境,从零构建一个面向对象的CyberGear微电机控制框架。该框架将复杂的CAN通信协议封装为简洁的API,开发者无需深究底层细节,即可轻松实现电机的速度、位置和扭矩控制,大幅简化机器人关节、云台等项目的开发流程。

oil88的博客 499

EDSR图像超分辨程序复现(踩坑及解决记录)

EDSR图像超分辨程序复现(踩坑及解决记录)

Sunny_Coder的博客 3642

预处理、编译、汇编、链接

C语言的编译链接过程要把我们编写的一个c程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接。编译就是把文本形式源代码翻译为机器语言形式的目标文件的过程。链接是把目标文件、操作系统的启动代码和用到的库文件进行组织形成最终生成可执行代码的过程 从图上可以看到,整个代码的编译过程分为编译和链接两个过程,编译对应图中的大括号括起的部分,其余则为链接过程。 过程图解如下: 编译过程又可以分成两个阶段:编译和汇编。 编译 编译是读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转

Chasing__Dreams的博客 2095

用Origin快速拟合荧光寿命、PL Decay (TRPL)数据分析处理

用Origin快速拟合荧光寿命、PL Decay (TRPL)数据分析处理

A20802013的博客 2万+

C语言编译过程详解

IDE的使用让很多和我一样的人对C/C++可执行程序的底层生成一知半解,不利于我们深入理解原理。在这里小结一下,望路过的大神指正~ 前言:从一个源文件(.c文件)到可执行程序到底经历了哪几步,我想很多人都知道,但是每一步具体做了什么,估计很多像我一样的人就不能说的清清楚楚,明明白白了。 C语言编译过程分成四个步骤: 1,由.c文件到.i文件,这个过程叫预处理 2,由.i文件到.s文件...

请叫我皮皮虾的博客 3359

动作识别(三)Win10复现OpenPose1.7.0+ST-GCN代码

动作识别(三)Win10复现OpenPose1.7.0+ST-GCN代码1.Win10系统配置OpenPose1.7.0的Python API 本人最近在研究基于骨架的动作识别方法,有幸看到端到端的ST-GCN算法,于是决定自己复现一下。(具体原理这里不介绍,大家自行查阅,比如Openpose是个啥?ST-GCN又是个啥?) 1.Win10系统配置OpenPose1.7.0的Python API 安装步骤: (1) ...

QIANFANGshiwo的博客 3041

【可穿戴算法开发】-PPG信号检测方法

文章目录一、PPG(光电容积脉搏波法)信号的检测原理二.PPG技术目前存在的问题(挑战)三. **心电信号产生的原理** 随着经济的发展,在人们生活水平提高的同时,高脂肪摄入和低运动量成为了人们普遍的生活模式,近年来高血压、高血脂已经发展为危险性最高的病症。心电、血压、血氧等生理参数是预防和分析心血管疾病的重要生理参数。 常用的心电测量仪器有:多导ECG心电图仪、PPG心率检测器、心率带等; 常...

wxq_1993的博客 2万+

C语言之编译链接全过程分析

C语言的编译链接过程要把我们编写的一个c程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接。编译就是把文本形式源代码翻译为机器语言形式的目标文件的过程。链接是把目标文件、操作系统的启动代码和用到的库文件进行组织,形成最终生成可执行代码的过程。过程图解如下: 从图上可以看到,整个代码的编译过程分为编译和链接两个过程,编译对应图中的大括号括起的部分,其余则为链接过程。

mcvsyy521的专栏 1750

c语言自定义头文件_c语言编译过程

这篇思考下C语言的编译过程,通过编译过程再看其它,也许会有不一样的理解。参与过程的结果,才会对结果有不一样的感觉。只追求结果,也许会得出“理所当然”的错觉,自己深陷其中,还浑然不觉。太多所谓的“客观”,到头来还只是个主观的理解,如此而已!学习c语言的第一节课,往往第一个接触的代码便是如图1所示的代码:#include int main(){ printf("hello world!...

weixin_39677538的博客 1224

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

C语言之程序环境、编译过程、宏与函数

一、程序编译过程 1.程序编译过程 组成一个程序的每个源文件通过编译过程分别转换成目标代码。 每个目标文件由链接器捆绑在一起。形成一个单一而完整的可执行程序。 链接器同时也会引入标准C函数库中任何被程序所用到的函数,而且它可以搜索程序库,将其需要的函数也链接到程序中。 2.编译过程 预处理,选项gcc -E test.c -o test.i预处理完成之后就停下来,预处理之后产生的结果都放...

Sheena997的博客 567

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

C语言编译过程总结

概述 C语言的编译链接过程要把我们编写的一个c程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接。编译就是把文本形式源代码翻译为机器语言形式的目标文件的过程。链接是把目标文件、操作系统的启动代码和用到的库文件进行组织形成最终生成可执行代码的过程。过程图解如下: 从图上可以看到,整个代码的编译过程分为编译和链接两个过程,编译对应图中的大括号括起的部分,其余则为链接过程。 编译过程 编译过程又可以分成两个阶段:编译和汇编。 编译 编译是读取源程序(字符流),对之进行词法和语法的分析,

TBAALi的博客 294

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

程序编译过程分析

1.概述 一个C语言程序从源代码文件变成最后的可执行程序文件,需要经历预处理、编译、汇编、链接四个过程。 预处理:条件编译、头文件包含、宏替换,生成.i文件 编译:将预处理后的文件转换成汇编语言,生成.s文件 汇编:汇编变为目标代码(机器代码)生成.o文件 链接:链接目标代码,生成可执行程序。 日常使用GCC编译器完成上述过程,需要以下选项: -E P...

夜黯竹亭风的博客 762

c语言编译全过程各个阶段分析

C语言编译全过程 编译的概念:编译程序读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,再由汇编程序转换为机器语言,并且按照操作系统对可执行文件格式的要求链接生成可执行程序。 编译的完整过程:C源程序-->预编译处理(.c)-->编译、优化程序(.s、.asm)-->汇编程序(.obj、.o、.a、.ko)-->链接程序(.exe、.elf、.ax

yt123456yt的专栏 902

C 语言编译过程总结详解

C 语言编译过程总结详解 从图上可以看到,整个代码的编译过程分为编译和链接两个过程,编译对应图中的大括号括起的部分,其余则为链接过程。 编译过程 编译过程又可以分成两个阶段:编译和会汇编。编译 编译是读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,源文件的编译过程包含两 1 个主要阶段:第一个阶段

上善若水 1248

[转]C++编译链接过程详解

C语言的编译链接过程要把我们编写的一个c程序(源代码)转换成可以在硬件上运行的程序(可执行代码),需要进行编译和链接。编译就是把文本形式源代码翻译为机器语言形式的目标文件的过程。链接是把目标文件、操作系统的启动代码和用到的库文件进行组织,形成最终生成可执行代码的过程。过程图解如下: 从图上可以看到,整个代码的编译过程分为编译和链接两个过程,编译对应图中的大括号括起的部分,其余则为链接过程...

Stephen___Qin的博客 96

C语言编译全过程

C语言编译全过程     编译的概念:编译程序读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,再由汇编程序转换为机器语言,并且按照操作系统对可执行文件格式的要求链接生成可执行程序。     编译的完整过程:C源程序-->预编译处理(.c)-->编译、优化程序(.s、.asm)-->汇编程序(.obj、.o、.a、.ko)-->链接程序(.exe、

静-静的雪 568

C语言入门学习——源文件的编译运行具体过程

本文介绍了C语言程序的编译执行过程。首先区分了编译型语言(C/C++)、解释型语言(Python)和混合型语言(Java)的特点。重点讲解了编译型语言的编译过程:预处理→编译为汇编代码→翻译为机器码→链接库文件生成可执行文件。文中还介绍了GCC、Clang等主流编译器,以及汇编语言作为底层语言的作用。通过类比说明编译器将源代码转换为二进制可执行文件的过程,帮助读者理解程序从编写到运行的完整流程。

2501_93553916的博客 727

C语音的预处理,编译,汇编,链接过程分析

C语音的预处理,编译,汇编,链接过程分析 1.C程序编译分为以下几步: 预处理 (生成 .i文件) 编译(生成 .s文件) 汇编(生成 .o文件) 链接(生成 .exe文件) 2.通过图解来理解编译过程 3.通过Linux的gcc编译C文件,并逐步分析: vim test.c //Linux指令 //test.c只写一个简单的hello world #include<stdi...

qq_43203949的博客 2314

可运行的C语言程序的拓展名,可运行的c语言程序的扩展名为什么?

可运行的c语言程序的扩展名为“.exe”。c语言程序经过“编译程序”编译之后,生成一个后缀为“.obj”的二进制文件;然后由“连接程序”,把此“.obj”文件与c语言提供的各种库函数连接在一起,生成一个后缀“.exe”的可执行文件。教程推荐:《c语言教程视频》C语言源程序经过C语言编译程序编译之后,生成一个后缀为“.OBJ”的二进制文件(称为目标文件),最后还要由称为“连接程序”(Link)的软件...

weixin_35843035的博客 4413

C 语言的编译与链接

在 C 语言编程的世界里,编译和链接是将我们编写的源代码转换为可执行程序的重要过程。理解这两个步骤对于编写高效、可靠的 C 语言程序至关重要。

Q741_147的博客 456

C的编译和链接

c语言中存在一些预定义符号__FILE__//进⾏编译的源⽂件__LINE__//⽂件当前的⾏号__DATE__//⽂件被编译的⽇期__TIME__//⽂件被编译的时间__STDC__//如果编译器遵循ANSI C,其值为1,否则未定义#define 机制是C/C++预处理器中的一个重要功能,它允许开发者定义宏(macro)来实现文本替换。

2302_81146716的博客 1095
上一篇: 深入理解 C 语言指针:从基础到高级应用
下一篇: C 语言文件操作入门:从基础到实战
THGML
博客等级 码龄3年 49粉丝 21原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值