发布时间:2026/9/4 17:23:01
C语言梦开始的地方21:编译和链接 文章目录C语言梦开始的地方21编译和链接翻译环境和运行环境翻译环境预处理编译词法分析语法分析语义分析汇编链接运行环境C语言梦开始的地方21编译和链接上一章我们了解了C语言的文件操作系统的数据文件和对数据的文件的各种操作。本章章节我们来了解一下C语言的.c文件是如何变成.exe文件的。翻译环境和运行环境在 ANSI C 的任何一种实现中存在两个不同的环境。第1种是翻译环境在这个环境中源代码被转换为可执行的机器指令二进制指令。第2种是执行环境它用于实际执行代码。那么翻译环境中的编译和链接做了哪些操作才使.c文件转换成了.exe文件呢翻译环境首先我们就得展开开讲解一下翻译环境所做的事情。其实翻译环境是由编译和链接两个大的过程组成的而编译又可以分解成预处理有些书也叫预编译、编译、汇编三个过程。一个C语言项目中可能存在多个.c文件一起构建那多个.c文件是如何生成可执行程序呢多个.c文件单独经过编译器编译处理生成对应的目标文件。注在Windows环境下的目标文件的后缀是.objLinux环境下目标文件的后缀是.o多个目标文件和链接库一起经过链接器处理生成最终的可执行程序。链接库是指运行时库(它是支持程序运行的基本函数集合)或者第三方库。通过上述的步骤才使.c文件构建成了我们能运行的.exe文件以GCC为例就是下面这种场景下面会出现一些gcc的命令使用这些命令并不需要去Linux上。我们只需要去安装一下VSCode和mingW即可。在VSCode中要安装一个C/C的插件。安装好后就可以编写和运行C/C代码了预处理在预处理阶段源文件和头文件会被处理成为.i为后缀的文件。在gcc环境下想观察一下对test.c文件预处理后的.i文件命令如下gcc-Etest.c-otest.i使用也很简单在VSCode中点击Ctrl 即可预处理阶段主要处理那些源文件中#开始的预编译指令。比如#include,#define处理的规则如下将所有的#define删除并展开所有的宏定义。处理所有的条件编译指令如#if、#ifdef、#elif、#else、#endif。处理#include 预编译指令将包含的头文件的内容插入到该预编译指令的位置。这个过程是递归进行的也就是说被包含的头文件也可能包含其他文件。删除所有的注释添加行号和文件名标识方便后续编译器生成调试信息等。或保留所有的#pragma的编译器指令编译器后续会使用。经过预处理后的.i文件中不再包含宏定义因为宏已经被展开。并且包含的头文件都被插入到.i文件中。所以当我们无法知道宏定义或者头文件是否包含正确的时候可以查看预处理后的.i文件来确认。编译编译过程就是将预处理后的文件进行一系列的词法分析、语法分析、语义分析及优化生成相应的汇编代码文件。编译过程的命令如下gcc-Stest.i-otest.s对下面代码进行编译的时候会怎么做呢假设有下面的代码array[index](index4)*(26);词法分析首先我们得先了解词法分析分析的是什么词法分析就像扫描器将源代码程序输入扫描器扫描器的任务就是简单的进行词法分析把代码中的字符分割成一系列的记号关键字、标识符、字面量、特殊字符等。比如将英文符号写成了中文符号“”inta10此时词法分析就像扫描器一样将int a 10进行分割 校验。回到我们最开始的代码问题上面程序进行词法分析后得到了16个记号记号类型array标识符[左方括号index标识符]右方括号赋值(左圆括号index标识符加号4数字)右圆括号*乘号(左圆括号2数字加号6数字)右圆括号常见的报错原因中文标点符号如中文分号、中文引号“”混入代码。字符串或字符常量缺少闭合引号如 char *s “hello;此时扫描器会一直扫描到文件末尾都找不到”报错 missing terminating character。语法分析语法分析则像解析器Parser根据语法规则检查记号流时发现结构不符合C语言的文法规则即语句结构写错了。上述代码在语法分析就如下图所示常见报错原因通常是大括号、括号、分号不匹配或者关键字使用位置错误。语义分析语义分析语法正确但语句的含义不符合语言规范。语义分析器Semantic Analyzer会检查类型系统、声明匹配、作用域规则等。常见报错原因类型不兼容、使用了未声明的变量/函数、重复定义、赋值类型冲突等。汇编汇编器是将汇编代码转转变成机器可执行的指令每一个汇编语句几乎都对应一条机器指令。就是根据汇编指令和机器指令的对照表一一的进行翻译也不做指令优化。gcc-ctest.s-otest.o汇编一般有一下用途读汇编是排查“挂死”和“栈溢出”的。写出“高性能”代码。比如操作是否是原子的理解“未定义行为”的诡异后果下面我们来简单的读一下C语言转汇编代码intmain(){inta10;intb20;intcab;returnc;}转换后的汇编代码.file test.c .text .globl main .def main; .scl 2; .type 32; .endef .seh_proc main main: pushq %rbp .seh_pushreg %rbp movq %rsp, %rbp .seh_setframe %rbp, 0 subq $48, %rsp .seh_stackalloc 48 .seh_endprologue call __main movl $10, -4(%rbp) movl $20, -8(%rbp) movl -4(%rbp), %edx movl -8(%rbp), %eax addl %edx, %eax movl %eax, -12(%rbp) movl -12(%rbp), %eax addq $48, %rsp popq %rbp ret .seh_endproc .def __main; .scl 2; .type 32; .endef .ident GCC: (Rev2, Built by MSYS2 project) 16.1.0看汇编通常是看中间汇编代码比如上述代码就是从call __main开始阅读movl $10, -4(%rbp) # 将 10 存入 rbp-4 地址变量 a movl $20, -8(%rbp) # 将 20 存入 rbp-8 地址变量 b movl -4(%rbp), %edx # 把 arbp-4的值放入 edx 寄存器 movl -8(%rbp), %eax # 把 brbp-8的值放入 eax 寄存器 addl %edx, %eax # eax edx eax 即 eax a b movl %eax, -12(%rbp) # 将 eax 的结果存回 rbp-12变量 c movl -12(%rbp), %eax # 将 c 的值放入 eax因为 eax 是返回值寄存器 addq $48, %rsp # 释放之前分配的 48 字节栈空间 popq %rbp # 恢复调用者的 rbp ret # 返回因为在不同的环境会得出不一样的汇编代码上述是在Windows 11的环境下使用VSCode运行出来的如果换成Linux那么汇编也会有所不同。链接链接是一个复杂的过程链接的时候需要把一堆文件链接在一起才生成可执行程序。链接过程主要包括地址和空间分配符号决议和重定位等这些步骤。链接解决的是一个项目中多文件、多模块之间互相调用的问题比如在一个C的项目中有2个.c文件test.c和add.c代码如下test.c#includestdio.hexternintAdd(intx,inty);externintg_val;intmain(){intx10,y20;printf(%d\n,Add(x,y));return0;}add.cintg_val2022;intAdd(intx,inty){returnxy;}test.c中调用了Add函数和使用了g_val变量但它们定义在add.c中。编译test.c时编译器不知道Add和g_val的地址因此暂时将这些引用搁置生成未解析的符号。链接时链接器在所有目标文件test.o和add.o及库中查找这些符号的定义找到后将test.o中所有引用Add和g_val的指令地址修正为真正的内存地址而这个地址修正的过程也被叫做重定位。gcc环境gcc test.o add.o-otestmsvc环境直接点击运行即可。运行环境载入内存有操作系统时由操作系统载入独立环境如嵌入式需手工安排或固化到ROM。程序启动调用 main 函数。运行时资源堆栈stack存储局部变量、函数返回地址等。静态内存static存储全局变量和静态变量程序运行期间一直保留。终止正常执行完毕main 返回或意外终止。我们在函数栈帧中再去了解运行环境。完

相关新闻

2026/9/4 17:23:01

盘点第二届世界人形机器人运动会的“乐子”与“门道”

【EI检索会议 | SPIE出版】 2026年智能计算与多模态信号处理国际学术会议(CIMSP 2026)-CSDN博客文章浏览阅读730次,点赞24次,收藏6次。2026年智能计算与多模态信号处理国际学术会议(CIMSP2026)将于8月21-23…

2026/9/4 17:23:01

基于YOLOv8的航拍滑坡检测实战:数据集构建与模型部署全流程

简介:本资源为面向遥感图像分析与地质灾害智能识别领域的航拍滑坡检测专用数据集,适用于计算机视觉初学者至中级研究者开展目标检测模型训练与算法验证。数据集共4315张512512分辨率航拍图像,全部标注为单类别“landslide”,配套4…

2026/9/4 17:23:00

滚动轴承故障诊断Python实战:从模型到工业部署

简介:本资源是一套面向计算机及相关专业本科生的滚动轴承故障诊断毕业设计实战项目,聚焦工业设备智能运维场景,为大作业、课程设计及毕业课题提供完整可复现的深度学习解决方案。资源包含41个文件,以30个CWRU轴承故障数据集MAT文件…

2026/9/4 18:13:08

基于SpringBoot的企业知识库问答系统毕业设计项目源码

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

2026/9/4 18:13:08

带宽:GPU 的粮道在哪里堵住了(发烫优化系列 · 第 2 篇)

上一篇我们说过一个反直觉的结论:手机发烫,烧的不是"算力",而是"搬运"——Arm 官方给出的数字是 DRAM 访问每 GB/s 要付 80–100mW 的电。 这一篇把这个结论的物理基础彻底讲透:带宽到底是什么、为什么在手机…

2026/9/4 18:13:08

基于SpringBoot的汽车咨询管理系统的设计与实现毕业设计项目源码

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

2026/9/4 18:13:08

K8S LVM扩容-【20260902】001篇

文章目录 一、根目录扩容(剩余约 95GiB 全部给 `/`) 1.1 新建分区 /dev/sda3(类型 LVM) 1.2 让内核重读分区表 1.3 扩容 LVM 与文件系统 二、部署 NFS Server 2.1 修复 yum 源(CentOS 7 EOL 必做) 2.2 创建共享目录 2.3 配置 /etc/exports 2.4 固定端口(便于防火墙放行)…

2026/9/4 18:13:08

全桥电路与PWM控制:从逆变到整流的统一硬件平台解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/4 18:08:08

工业视觉实战:基于全连接神经网络的喷码字符识别系统构建

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/3 18:28:26

vSound小提琴数字处理器实操指南:从接线到演出的完整配置

电小提琴或者原声小提琴插电演出,第一个绕不开的坎就是声音难听。原声琴的共鸣和空气感一旦进了拾音器,出来的往往是一坨干瘪、发尖、带着奇怪塑料味的信号。我当初第一次把琴接上乐队调音台,直接被主唱吐槽"你这声音像在锯钢丝"。…

2026/9/3 14:29:47

传感器接口IC如何攻克生物化学传感的微弱信号难题?

1. 从电极到比特流:为什么生物化学传感必须依赖专用接口IC 做生物化学传感的人都有过类似的经历:明明传感器本身性能很好,信号输出却一塌糊涂——噪声大、漂移明显、重复性差,怎么调都达不到预期。很多时候问题并不在传感器&#…

2026/9/3 14:30:35

STM32F411CEU6多通道ADC采集:扫描模式+DMA实现详解

1. 多通道 ADC 的用武之地把“Multichannel ADC”和“STM32F411CEU6”这两个关键字放在一起,其实就是嵌入式开发里最常遇到的一类需求:用一块不算贵的 MCU,同时采集多路模拟信号。STM32F411CEU6 是 48 引脚的 Cortex-M4F 主控,主频…

2026/9/4 0:00:58

STM32H743 SPI从机DMA双缓冲通信实战

简介:本资源是面向嵌入式开发工程师与STM32进阶学习者的SPI DMA双机通信从机端完整实现方案,聚焦STM32H743高性能Cortex-M7单片机在工业控制与高速数据交互场景下的从机通信开发痛点。压缩包含1355个文件,主体为599个C源码与321个头文件&…

2026/9/4 0:00:58

CPU开盖降温教程:20元成本让温度直降30度的原理与实践

最近很多朋友都在抱怨,自己的电脑一到夏天就变成"烤箱",玩游戏时CPU温度动不动就飙到90度以上,风扇噪音堪比直升机。更让人头疼的是,明明配置不错,却因为高温降频导致性能大打折扣。如果你也遇到了类似问题&…

2026/9/4 0:00:58

ArkTS 表单工程:场地预约页的三态场次 Grid 与校验

ArkTS 表单工程:场地预约页的三态场次 Grid 与校验 App 14「运动场地预约」场地 Tab(Func1Tab),是整 App 交互最丰富的页面——场地横向切换 三色图例 渐变预约预览卡 快捷模板 今日场次 Grid(可选/已选/已满三态&…

2026/9/3 20:43:36

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/3 17:51:43

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/3 21:06:57

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…