编译过程

编译过程是将高级编程语言(如 C 语言)写成的源代码转换成机器可以执行的低级机器语言(通常是二进制代码)的过程。这个过程一般可以分为几个阶段:

  1. 预处理(Preprocessing):

    • 预处理器指令,如 #include#define 和条件编译指令 #ifdef#endif 等被处理。
    • 头文件内容(包含在源文件中的 .h 文件)是插入到源代码中的。
    • 宏替换发生在这个阶段。
    • 预处理器还会去除注释,并扩展所有预处理指令。
  2. 编译(Compilation):
    • 预处理过的代码被编译器转换成汇编语言。
    • 编译器进行词法分析、语法分析、语义分析和中间代码生成。
    • 此外,编译器进行了优化的处理,消除不必要的代码,优化循环和减少空间和时间的消耗。
  3. 汇编(Assembly):
    • 汇编程序将汇编语言转换成机器语言,生成所谓的目标代码(通常是 .o.obj 文件)。
    • 汇编语言是一种低级语言,但它是使用符号编码而不是二进制。
  4. 链接(Linking):
    • 在链接阶段,一个或者多个目标代码文件被合并,并与库代码链接一起生成一个可执行文件。
    • 链接器解决程序中对库函数和其他模块的调用。
    • 如果程序中有多个文件,则需要将它们的目标代码与所需的库文件一起链接。

通常这四个步骤是自动进行的,程序员只需通过一个编译命令就能完成这个过程。例如,当你在 C 语言的开发环境中输入 gcc main.c -o main 并按下回车,上述所有步骤都由 gcc 编译器自动完成,并最终生成名为 main 的可执行文件。

详尽的编译过程可能会更加复杂,因为编译器优化可以包含许多不同的技术和优化阶段。同时,现代编译器可能在内部使用更多抽象表示形式来转换和优化代码,直到最后生成目标代码。

使用编译工具分步编译

要使用 cc 编译一个包含多个 C 文件的项目,你通常需要分两个步骤进行:编译和链接。下面是一个分步的基本示例,假设你有一个主源文件 main.c 和一个源文件 file.c,以及它依赖的头文件 file.h

  1. 分别编译每个源文件为目标文件:

    cc -c main.c
    cc -c file.c

    这里,-c 标志告诉 cc 编译器生成目标文件而不是完成整个链接过程。生成的目标文件为 main.ofile.o

  2. 将所有的目标文件链接成一个可执行文件:

    cc file.o main.o -o program

在这个命令中,所有的 .o 目标文件被链接起来以生成最终的可执行文件 program

如果你的项目比较复杂,包含许多源文件和依赖,手动管理这个过程可能变得很繁琐。在这种情况下,可以使用构建系统(如 make、CMake 或 Meson)来自动化编译和链接的过程。例如,你可以创建一个 Makefile 来简化操作:

# Makefile 示例
CC=cc # 定义编译器
CFLAGS=-c -Wall # 定义编译标志
LDFLAGS= # 定义链接标志,如需要可以添加 -lm 来链接数学库
SOURCES=main.c file.c # 定义源文件列表
OBJECTS=$(SOURCES:.c=.o) # 自动推导出目标文件列表
EXECUTABLE=program # 定义最终的可执行文件名 all: $(SOURCES) $(EXECUTABLE) $(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $@ .c.o:
$(CC) $(CFLAGS) $< -o $@ clean:
rm -f $(OBJECTS) $(EXECUTABLE)

然后,只需在包含 Makefile 的目录中运行 make 命令,make 会自动处理编译和链接的整个过程。make clean 命令会清理所有生成的目标文件和可执行文件,这样你可以重新开始编译过程。这是一种更高级的自动化处理方式,它在大型项目中非常有用。

推荐阅读:C 编译过程与库文件的作用

C 语言编译过程的更多相关文章

  1. C语言编译过程及数据类型

    写在前面 C语言可以称得上是高级语言中的低级语言,接下来一段时间,我会写一下文章关于c语言,把它的神秘面纱一 一揭开.下面主要是c语言的C语言编译过程及数据类型 源文件编译过程 为了使计算机能执行高级 ...

  2. C语言编译过程以及gcc编译参数

    1.1       C语言编译过程,gcc参数简介 1.1.1          C语言编译过程 一.gcc - o a a.c -o:指定文件输出名字 二.C语言编译的过程: 1.1.1       ...

  3. 转 C语言编译过程简介

    C语言编译过程简介 C语言编译过程简介 刚开始接触编程的时候,只知道照书敲敲代码,一直都不知道为什么在windows平台下代码经过鼠标那样点击几下,程序的结果就会在那个黑色的屏幕上.现在找了个机会将C ...

  4. GCC 使用-C语言编译过程

    任何一种高级语言,要想在机器上执行,必须翻译为机器能读懂的机器语言.编译器就相当于翻译官,将高级语言翻译为机器语言. GCC 最初只用了编译 C 语言程序,全称是 GNU C Compiler.后来扩 ...

  5. Go 语言编译过程

    走进Golang之编译器原理_大愚Talk-CSDN博客 https://blog.csdn.net/hel12he/article/details/103061921 go编译器 - 知乎 http ...

  6. go语言编译过程概述

    go语言编译过程概述 总结自<go语言设计与实现> 名词解释: 中间代码 中间代码是编译器或者虚拟机使用的语言,它可以来帮助我们分析计算机程序.在编译过程中,编译器会在将源代码转换到机器码 ...

  7. C语言编译过程

    GCC编译C源码有四个步骤: 预处理-----> 编译 ----> 汇编 ----> 链接 一. 编译和链接的流程 C语言的编译链接过程要把我们编写的一个c程序(源代码)转换成可以在 ...

  8. C语言编译过程详解

    前言 C语言程序从源代码到二进制行程序都经历了那些过程?本文以Linux下C语言的编译过程为例,讲解C语言程序的编译过程. 编写hello world C程序: // hello.c #include ...

  9. C语言编译过程(转)

    内容摘要 : C语言编译的整个过程是非常复杂的,里面涉及到的编译器知识.硬件知识.工具链知识都是非常多的,深入了解整个编译过程对工程师理解应用程序的编写是有很大帮助的,希望大家可以多了解一些,在遇到问 ...

  10. C语言基础(21)-C语言编译过程及GCC参数简介

    任何C语言的编译过程可分为以下三部分: 一.预编译 在C语言中,以#开头的语句又叫预编译指令.预编译主要做以下两件事情: 1.将#include包含的头文件做简单的文本替换: 2.将代码中的注释删除. ...

随机推荐

  1. python爬虫-xpath基础

    # 准备一个html格式文档 doc = ''' <div> <ul> <li class="item-0"><a href=" ...

  2. (转载)linux命令英文缩写的含义(方便记忆)

    linux常用命令的英文单词缩写 命令缩写: ls:list(列出目录内容) cd:Change Directory(改变目录) su:switch user 切换用户rpm:redhat packa ...

  3. Linux 命令指南

    做这个东西有两个用处,一是初赛会考,二是考场上用 windows 哪里数组越界你都不知道直接 RE 爆炸. sudo -s 输入后填写密码获得管理员权限. cd 打开文件或者目录,用法是 cd 目录名 ...

  4. 如何在 Windows 使用 Podman Desktop 取代 Docker Desktop

    Podman Desktop 是 Docker Desktop 的免费替代品,是本地开发使用的另一个绝佳选择.它提供了类似的功能集,同时保持完全开源,让您避免使用 Docker 产品的许可问题.在本文 ...

  5. C#皮肤美化

    关于Winform窗体美化,目前大致了解是有两种方式:第一种方式是重写Winform本身的控件,不过这需要非常熟悉控件的各个属性和事件并且要求具有很高的GDI绘图技术.第二种方式是借助第三方Winfo ...

  6. weui weui-switch 开关取值,设置默认状态

    html <div class="weui-cell__ft"> <input class="weui-switch" type=" ...

  7. ps -ef | grep xxx 解释

    上述内容为:命令拆解: ps:将某个进程显示出来-A 显示所有程序.-e 此参数的效果和指定"A"参数相同.-f 显示UID,PPIP,C与STIME栏位.grep命令是查找中间的 ...

  8. django 信号第一个 raise ValidationError出现后,还会继续下一个if吗

    在你提供的代码片段中,如果第一个 raise ValidationError 触发,会抛出异常并停止执行当前函数或代码块.这是因为异常(Exception)会中断正常的代码流程,将控制权传递给调用堆栈 ...

  9. [oeasy]python0009 - 设置断点_break_point

    ​ 调试程序 回忆上次内容 ​py​​ 的程序是按照顺序执行的 是一行行挨排解释执行的 程序并不是数量越多越好 kpi也在不断演化 ​ 编辑 写的代码越多 出现的bug就越多 那什么是bug呢? 如何 ...

  10. java spring boot 权限认证总结瞎记一通,各种 方案。附近如何运行jar包。和如何读配文件

    在正式笔之 前先来思考如何将java 的包打包成jar 包同,运行时指定配置,这样运行, 以上问题有空在来研究,有空在来补这个文档 首先呢,先来说说Session 怎么使用,这个在sping boot ...