当前位置: 首页 > news >正文

【C语言】C语言 4 个编译过程详解

C语言的编译过程涉及几个关键步骤、概念和细节,每个步骤都有助于将人类可读的源代码转换为可执行的机器码。以下是详细的解释和示例:

一、什么是编译?

编译是将源代码转换为目标代码的过程。它是在编译器的帮助下完成的。编译器检查源代码是否存在语法或结构错误,如果源代码没有错误,则生成目标代码。

在这里插入图片描述

c 编译过程将作为输入的源代码转换为目标代码或机器代码。编译过程可分为预处理、编译、汇编和链接四个步骤。
在这里插入图片描述

二、编译过程中的步骤:

  1. 预处理

    • 概念:预处理器 (cpp) 处理以 # 开头的指令,如 #include#define#ifdef。它通过展开宏和包含头文件来准备源代码进行编译。
    • 细节:将源代码转换为预处理后的中间形式。源代码是在文本编辑器中编写的代码,源代码文件的扩展名为 .c。此源代码首先传递给预处理器,然后预处理器扩展此代码。展开代码后,扩展的代码将传递给编译器。
    • 示例
      #include <stdio.h>
      #define MAX 100int main() {printf("Max value: %d\n", MAX);return 0;
      }
      
    • 后缀.i (生成的预处理后的源文件)。
  2. 编译

    • 概念:编译器 (gcc, clang) 将预处理后的源代码翻译成特定于目标体系结构的汇编语言。
    • 细节:执行词法分析、语法分析、语义分析和优化。由预处理器扩展的代码将传递给编译器。编译器将此代码转换为汇编代码。或者我们可以说 C 编译器将预处理的代码转换为汇编代码。
    • 示例
      mov eax, 42
      
    • 后缀.s (生成的汇编代码文件)。
  3. 汇编

    • 概念:汇编器 (as) 将汇编代码转换为可重定位的机器码(目标代码)。
    • 细节:将汇编指令转换为机器码指令。使用汇编程序将汇编代码转换为目标代码。汇编程序生成的目标文件的名称与源文件的名称相同。在 DOS 中,目标文件的扩展名是 .obj,在 UNIX 中,扩展名是 .o。如果源文件的名称为 hello.c,则目标文件的名称将为 hello.obj
    • 示例
      00000000: B8 2A 00 00 00        mov eax, 0x2a
      
    • 后缀.o (生成的目标文件)。
  4. 链接

    • 概念:链接器 (ld) 将多个目标文件组合在一起,并解决外部引用,生成最终的可执行代码。
    • 细节:执行符号解析、为变量和函数分配最终地址,并链接必要的库文件。主要是,所有用 C 编写的程序都使用库函数。这些库函数是预先编译的,并且这些库文件的目标代码以 .lib(或 .a)扩展名存储。链接器的主要工作是将库文件的目标代码与我们程序的目标代码相结合。有时,当我们的程序引用其他文件中定义的函数时,会出现这种情况;那么 linker 在这方面起着非常重要的作用。它将这些文件的目标代码链接到我们的程序。因此,我们得出结论,链接器的工作是将程序的目标代码与库文件和其他文件的目标代码链接起来。链接器的输出是可执行文件。可执行文件的名称与源文件的名称相同,但仅在扩展名上有所不同。在DOS中,可执行文件的扩展名为 .exe,而在UNIX中,可执行文件可以命名为 a.out。例如,如果我们在程序中使用 printf() 函数,则链接器会将其关联的代码添加到输出文件中。
    • 示例
      gcc main.o helper.o -o myprogram
      
    • 后缀:(可执行文件通常没有特定的后缀,常见的是没有后缀或 .out)。

三、其他概念和细节:

  • 编译器优化:提升代码性能和大小。
  • 目标文件:包含机器码和符号。
  • 静态与动态链接:静态链接库和动态链接库的嵌入与运行时链接。
  • 可执行文件格式:各种操作系统特定的格式(如 ELF、PE)。
  • .hex.bin 文件通常不是C语言编译过程的直接产物,而是在嵌入式系统开发中常见的文件格式,用于存储程序或数据的二进制表示。这些文件通常是在程序已经编译、链接并生成了可执行文件之后,通过特定的工具或者转换过程生成的。因此,它们不属于C语言编译过程的标准阶段,但是在嵌入式开发中是非常常见的文件格式。
  • .hex 文件:通常用于存储以十六进制格式表示的固件或程序映像,适用于多种嵌入式系统和芯片编程器。
  • .bin 文件:通常用于存储原始的二进制数据,可以包括程序或者数据文件,常见于嵌入式系统和低级系统编程中。

示例 1 解释:

对于给定的C程序示例:

#include <stdio.h>
#define MAX 100int main() {printf("Max value: %d\n", MAX);return 0;
}
  • 预处理:展开 #include <stdio.h> 并将 MAX 替换为 100
  • 编译:将C源代码转换为汇编语言。
  • 汇编:将汇编指令转换为机器码。
  • 链接:将机器码与标准库函数(如 printf)结合,生成最终的可执行文件。

示例 2 解释:

hello.c :

#include <stdio.h>  
int main()  
{  printf("Hello World !");  return 0;  
} 

现在,我们将创建上述程序的流程图:

在这里插入图片描述

在上面的流程图中,执行程序需要执行以下步骤:

  1. 首先,将输入文件(即 hello.c)传递给预处理器,预处理器将源代码转换为扩展的源代码。扩展源代码的扩展将是 hello.i
  2. 扩展的源代码将传递给编译器,编译器将此扩展的源代码转换为汇编代码。程序集代码的扩展名为 hello.s
  3. 然后,将此汇编代码发送到汇编程序,汇编程序将程序集代码转换为目标代码。
  4. 创建目标代码后,链接器将创建可执行文件。然后,加载程序将加载执行的可执行文件。

理解这些步骤有助于优化代码、调试问题,并了解C编程中的平台特定细节。

相关文章:

【C语言】C语言 4 个编译过程详解

C语言的编译过程涉及几个关键步骤、概念和细节&#xff0c;每个步骤都有助于将人类可读的源代码转换为可执行的机器码。以下是详细的解释和示例&#xff1a; 一、什么是编译&#xff1f; 编译是将源代码转换为目标代码的过程。它是在编译器的帮助下完成的。编译器检查源代码是…...

Linux 常见的几种编辑器的操作步骤

在大多数命令行文本编辑器中&#xff0c;保存并关闭文件的操作方式基本相似。以下是常见的几种编辑器的操作步骤&#xff1a; 使用 vi 编辑器保存并关闭文件 编辑文件&#xff1a; sudo vi /path/to/file 编辑内容&#xff1a; 按 i 进入插入模式&#xff0c;编辑文件内容。 …...

LabVIEW汽车转向器测试系统

绍了一种基于LabVIEW的汽车转向器测试系统。该系统集成了数据采集、控制和分析功能&#xff0c;能够对转向器进行高效、准确的测试。通过LabVIEW平台&#xff0c;实现了对转向器性能参数的实时监测和分析&#xff0c;提升了测试效率和数据精度&#xff0c;为汽车转向器的研发和…...

image媒体组件属性配合swiper轮播

图片组件&#xff08;image&#xff09; 先插入个图片试试&#xff0c;插入图片用src属性&#xff0c;这是图片&#xff1a; 代码如下&#xff1a; <template><view><swiper indicator-dots indicator-color "#126bae" indicator-active-color &…...

nginx的匹配及重定向

一、nginx的匹配&#xff1a; nginx中location的优先级和匹配方式&#xff1a; 1.精确匹配&#xff1a;location / 对字符串进行完全匹配&#xff0c;必须完全符合 2.正则匹配&#xff1a;location ^~ ^~ 前缀匹配&#xff0c;以什么为开头 ~区分大小写的匹配 ~* 不区分…...

云计算【第一阶段(23)】Linux系统安全及应用

一、账号安全控制 1.1、账号安全基本措施 1.1.1、系统账号清理 将非登录用户的shell设为/sbin/nologin锁定长期不使用的账号删除无用的账号 1.1.1.1、实验1 用于匹配以/sbin/nologin结尾的字符串&#xff0c;$ 表示行的末尾。 &#xff08;一般是程序用户改为nologin&…...

YUM——简介、安装(Ubuntu22.04)

1、简介 YUM&#xff08;Yellowdog Updater, Modified&#xff09;是一个开源的命令行软件包管理工具&#xff0c;主要用于基于 RPM 包管理系统的 Linux 发行版&#xff0c;如 CentOS、Red Hat Enterprise Linux (RHEL) 和 Fedora。YUM 使用户能够轻松地安装、更新、删除和管理…...

Java面向对象练习(4.文字格斗游戏)(2024.7.4)

角色类 package FightGame20240704; import java.util.Random; public class GameRole {Random r new Random();private String name;private int blood;private char gender;private String face;public GameRole(){}public GameRole(String name, int blood, char gender){…...

Python获取QQ音乐歌单歌曲

准备工作 歌单分享的url地址 比如&#xff1a; https://i.y.qq.com/n2/m/share/details/taoge.html?hosteuinoKvzoK4l7evk7n**&id9102222552&appversion130605&ADTAGwxfshare&appshareiphone_wx 代码实现 def mu(share_url):share_url share_url.split(id…...

Linux系统部署MongoDB开源文档型数据库并实现无公网IP远程访问

文章目录 前言1. 安装Docker2. 使用Docker拉取MongoDB镜像3. 创建并启动MongoDB容器4. 本地连接测试5. 公网远程访问本地MongoDB容器5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定TCP地址远程访问 &#x1f4a1; 推荐 前些天发现了一个巨牛的人工智能学习网站&am…...

WPF Menu实现快捷键操作

很多小伙伴说&#xff0c;在Menu中&#xff0c;实现单个快捷键操作很简单&#xff0c;怎么实现多个快捷键操作和&#xff0c;组合快捷键呢&#xff0c;今天他来了。 上代码和效果图 一、Ctrl Shift 任意子母键实现快捷键组合 <Window x:Class"XH.TemplateLesson.M…...

VSCode常用的一些插件

Chinese (Simplified) 汉语&#xff08;简体&#xff09;拓展包。 Auto Close Tag 可以自动增加xml/html的闭合标签。 CodeSnap 截图神器。截图效果在下面。 Dracula Official vscode一个很好看的主题。 Git Graph git管理工具。 GitHub Repositories 有了它&#xff0c;不…...

OV通配符证书用于什么单位

OV&#xff08;Organization Validation&#xff09;通配符SSL证书是一种专门为组织或企业设计的SSL证书类型&#xff0c;它不仅提供了标准的SSL加密功能&#xff0c;还包含了对组织身份的验证。这种证书非常适合以下几种类型的单位使用&#xff1a; 企业级网站&#xff1a; …...

【数据结构】06.栈队列

一、栈 1.1栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out)的原则。 压栈&#…...

完全理解C语言函数

文章目录 1.函数是什么2.C语言中的函数分类2.1 库函数2.1.1 如何使用库函数 2.2自定义函数 3.函数的参数3.1 实际参数&#xff08;实参&#xff09;3.2 形式参数&#xff08;形参&#xff09; 4.函数调用4.1传值调用4.2 传址调用4.3 练习 5.函数的嵌套调用和链式访问5.1 嵌套调…...

性能测试:JMeter与Gatling的高级配置

性能测试是软件开发过程中不可或缺的一部分&#xff0c;它帮助我们确保应用在高负载下仍能保持良好的响应时间和稳定性。本文将深入探讨两种流行的性能测试工具&#xff1a;Apache JMeter和Gatling&#xff0c;并提供详细的高级配置指南以及Java代码示例。 Apache JMeter 高级…...

Linux 软件管理

Linux 软件管理 在 Linux 系统中&#xff0c;RPM&#xff08;Red Hat Package Manager&#xff09;和 YUM&#xff08;Yellowdog Updater, Modified&#xff09;是用于软件包管理的重要工具。 RPM RPM 是由 Red Hat 公司开发的软件包管理系统。 RPM 软件包通常具有 .rpm 扩…...

五.核心动画 - 图层的变换(平移,缩放,旋转,3D变化)

引言 在上一篇博客中&#xff0c;我们研究了一些视觉效果&#xff0c;在本篇博客中我们将要来讨论一下图层的旋转&#xff0c;平移&#xff0c;缩放&#xff0c;以及可以将扁平物体转换成三维空间对象的CATransform3D。 图层变换 图层的仿射变换 在视图中有一个transform属…...

Linux系统编程——线程基本概念

目录 一&#xff0c;关于多线程 二&#xff0c;重新理解进程 三&#xff0c;线程VS进程 四&#xff0c;线程周边概念 4.1 线程的数据共享 4.2 线程的优点 4.3 线程的缺点 4.4 线程异常 4.5 线程用途 五&#xff0c;一些问题解答 如何理解将资源分配给各个线程&…...

【HALCON】如何实现hw窗口自适应相机拍照成像的大小

前言 在开发一个喷码检测软件的时候碰到相机成像和hw窗体的大小不一致&#xff0c;hw太小显示不完全成像的图片&#xff0c;这使得成像不均匀&#xff0c;现场辨别起来比较不直观&#xff0c;因此需要对其进行一个调整。 解决 省略掉读取图片的环节&#xff0c;我们只需要将…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...