【C语言】编译与链接

news2024/10/5 21:20:27

1.翻译环境与运行环境

在ANSI C的任何一种实现中,存在两个不同的环境。

1.翻译环境,在这个环境中源代码被转换为可执行的机器指令(二进制指令)

2.执行环境,它用于实际执行代码

 

 2.翻译环境

那么翻译环境是怎么将源代码转换为可执行的机器指令的呢?这里我们就得展开讲解一下翻译环境所做的事情。

其实翻译环境由编译链接两个大的过程组成,而编译又可以分解成三个部分:预处理(也叫预编译)、编译、汇编。

一个C语言的项目中可能由多个.c文件一起构建

多个.c文件生成可执行程序又可分为一下几个步骤:
多个. c文件单独经过编译器,编译处理生成对应的目标文件(在windows环境下目标文件的后缀是.obj,Linux环境下目标文件的后缀是.o)。

多个目标文件和链接库一起经过链接处理生成最终的可执行程序(链接库是指运行库(它是支持程序运行的基本函数集合)或者第三方库)。

如果再把编译器展开成三个过程,那就变成了下面的过程:

2.1 预处理(预编译)

在预处理阶段,源文件和头文件会被处理为.i为后缀的文件。

gcc环境下观察一下,对test.c文件预处理后的.i文件,命令如下:

gcc  -E  test.c  -o test.i

预处理阶段主要处理那些源文件中#开始的预处理指令,比如:#include,#define,处理的规则如下:

将所有的#define删除,并展开所有的宏定义。

处理所有的条件编译指令,如#if,#iddef,#elif,#endif

处理#include预编译指令,将包含的头文件的内容插入到该预编译指令的位置。这个过程是递归进行的,也就是说被包含的头文件也可能包含其他文件。

删除所有的注释(也就是你对代码的解释,即//后面的文字)

比如:

test.c中的代码为:

#include<stdio.h>
int main()
{
    printf("hello world");//打印hello worle
    return 0;
}

在生成的test.i中就会把注释删掉

添加行号和文件名标识,方便后续编译器生成调试信息等。

或保留所有的#pragma的编译器指令,编译器后续会使用。

经过预处理后的.i文件中不在包含宏定义,因为宏已经被展开。并且包含头文件都被插到.i 文件中。所以当我们无法知道宏定义或者头文件是否被正确包含的时候,可以查看预处理的.i文件来确认。

 2.2 编译

编译过程就是将预处理后的文件进行一系列的·:词法分析、语法分析、语义分析及优化,生成相应的汇编代码文件。

编译过程的命令如下:

gcc -S test.i -o test.s

 那么对下面代码进行编译的时候,会这么做呢?

array[index]=(index+4)*(2+6)

首先对其进行词法分析 

将源代码程序被输入扫描器,扫描器的任务就是简单的进行词法分析,将代码中的字符分割成一系列的记号(关键字、标识符、字面量、特殊字符等)。

对上面代码进行词法分析得到了16个记号:

接下来进行语法分析:

语法分析器将对扫描产生的记号进行语法分析,从而产生语法树。这些语法树是以表达式为节点的树。

最后进行语义分析:

语义分析器来完成语义分析,即对表达式的语法层面分析。编译器所能做的分析是语义的静态分析。静态语义分析通常包括声明和类型的匹配、类型的转换等。这个阶段会报告错误的语法信息。

(如果想要进一步了解编译过程,可以去看看《编译原理》这一本书) 

2.3 汇编

汇编器是将汇编代码转变成为机器可执行的指令,每一个汇编语句几乎都对应一条机器指令(二进制指令)。就是根据汇编指令和机器指令的对照表一一的进行翻译,也不做指令优化。

汇编的命令如下:

gcc -c test.s -o test.o

2.4 链接

链接是一个复杂的过程,链接的时候需要把一堆文件链接在一起才可以生成可执行程序。

链接过程主要包括:地址和空间分配,符号决议和重定义等这些步骤。

链接解决的是一个项目多文件、多模块之间相互调用的问题。

比如:

在一个c项目中有两个.c文件(test.c和add.c),代码如下:
test.c:

#include <stdio.h>
//test.c
//声明外部函数
extern int Add(int x, int y);
//声明外部的全局变量
extern int g_val;
int main()
{
 int a = 10;
 int b = 20;
 int sum = Add(a, b);
 printf("%d\n", sum);
 return 0;
}

add.c:

int g_val = 2022;
int Add(int x, int y)
{
 return x+y;
}

 我们已经知道,每个源文件都是单独经过编译器处理形成对应的目标文件。

test.c经过编译处理生成test.o

add.c经过编译处理生成add.o

我们在test.c文件中使用了add.c文件中的Add函数和g_val变量。

我们在test.c文件每一次使用Add函数和g_val的时候必须确切的知道Add和g_val的地址,但是由于每个文件是单独编译的,在编译器编译test.c的时候并不知道Add函数和g_val变量的地址,所以暂时把Add的指令的目标地址和g_val的地址搁置。等待最后链接的时候由编译器等根据引用的符号Add在其他模块查找Add函数的地址,然后将test.c中所有引用到Add的指令重新修正,让他们的目标地址成为真正的Add函数的地址,对于全局变量g_val也是类似的方法来修正地址。这个地址修正的过程也被叫做:重定位。

3. 运行环境

1.程序必须载入内存中。在由操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。

2.程序开始执行代码。接着使用main函数。

3.开始执行程序代码。这个时候程序将使用一个运行时堆栈(stack),存储函数局部变量和返回值地址。程序同时也可以使用静态(static)内存,存储于静态变量在程序的整个执行过程一直保留他们的值。

4.终止程序。正常终止main函数,也有可能时意外终止。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1630837.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Docker】docker部署lnmp和wordpress网站

环境准备 docker&#xff1a;192.168.67.30 虚拟机&#xff1a;4核4G systemctl stop firewalld systemctl disable firewalld setenforce 0 安装docker #安装依赖包 yum -y install yum-utils device-mapper-persistent-data lvm2 #设置阿里云镜像 yum-config-manager --add…

vue3学习笔记-快速上手

创建第一个vue3的应用 之前看书学习vue,书籍对应的版本是vue2,今天群里看小伙伴聊天&#xff0c;觉得他们说得对 &#xff0c;反正是从零开始学&#xff0c;而且vue2都不维护了&#xff0c;那为什么不直接学习vue3呢&#xff0c;于是乎&#xff0c;又开启了从0学vue3之路。 参考…

Linux之进程间通信(二)

system V system V共享内存是内核中专门设计的通信的方式, 粗粒度划分操作系统分为进程管理, 内存管理, 文件系统, 驱动管理.., 粒度更细地分还有 进程间通信模块. 对于操作系统, 通信的场景有很多, 有以传送数据, 快速传送数据, 传送特定数据块, 进程间协同与控制以目的, 它…

一键设置jdk环境脚本

自动化脚本 一、使用方法 创建一个txt文本&#xff0c;放在和jdk存放的同一目录下&#xff0c;复制粘贴进我的代码&#xff0c;利用全局替换&#xff0c;将jdk1.8,改成你自己的jdk包名字&#xff0c;再重新把这个文件保存为.vbs文件。然后运行就行了 MsgBox "Runing s…

线上社交app的搭建,圈子社交系统,小程序+app+H5三端,源码交付,支持二开!

在科技飞速发展的大背景下&#xff0c;年轻人社交不再局限于面对面&#xff0c;线上社交app已深入各大年轻人的手机中。相比于传统交友方式&#xff0c;线上社交app为用户提供了更加新奇的交友体验。同时&#xff0c;它还可以吸引更多的朋友&#xff0c;提高用户的整体交友体验…

第4篇:创建Nios II工程之Hello_World<三>

Q&#xff1a;接着我们再来完成Nios II软件工程设计部分。 A&#xff1a;从Quartus Tools选择Nios II Software Build Tools for Eclipse&#xff0c;打开Nios II SBT软件&#xff0c;Workspace指定到hello_world工程的software文件夹路径&#xff1b;再从File-->New-->…

Java学习13

目录 一.内部类: 1.概念&#xff1a; 2.内部类的分类&#xff1a; &#xff08;1&#xff09;定义在外部类的局部位置上&#xff08;通常在方法体中&#xff09;&#xff1a; 1. 局部内部类&#xff08;有类名&#xff09; 2.匿名内部类&#xff08;无类名-重点&#xff01;…

Linux 基础命令使用创建用户

浏览网站的时候图片&#xff0c;看到一个小练习。创建用户分别位于不同的用户组。 解答下面的题目 2、建立用户使用 useradd&#xff0c;设置密码使用passwd的命令。大概不会使用命令可以借助man来解答。 先建立用户组&#xff1a; groupadd group1 # group1 不存在先建立&…

Redis底层数据结构之ZSkipList

目录 一、概述二、ZSkipList结构三、和平衡树和哈希表的对比 redis底层数据结构已完结&#x1f44f;&#x1f44f;&#x1f44f;&#xff1a; ☑️redis底层数据结构之SDS☑️redis底层数据结构之ziplist☑️redis底层数据结构之quicklist☑️redis底层数据结构之Dict☑️redis…

可替代IBM DOORS的现代化需求管理解决方案Jama Connect,支持数据迁移及重构、实时可追溯性、简化合规流程

作为一家快速发展的全球性公司&#xff0c;dSPACE一直致力于寻找保持领先和优化开发流程的方法。为推进其全球现代化计划&#xff0c;dSPACE开始寻找可以取代传统需求管理平台&#xff08;IBM DOORS&#xff09;的需求管理解决方案。 通过本次案例&#xff0c;您将了解dSPACE为…

【YOLO 系列】基于YOLO V8的火灾烟雾监控检测识别系统【python源码+Pyqt5界面+数据集+训练代码】

摘要&#xff1a; 火灾烟雾的及时检测对于人们的生命财产安全至关重要。然而&#xff0c;在大多数情况下&#xff0c;火灾往往在被发现时已经进展到了难以控制的阶段&#xff0c;这导致了严重的后果。为了解决这一问题&#xff0c;我们提出了基于深度学习技术的火灾烟雾检测系…

前端开发攻略---介绍HTML中的<dialog>标签,浏览器的原生弹框。

1、演示 2、介绍 <dialog> 标签用于定义对话框&#xff0c;即一个独立的窗口&#xff0c;通常用来显示对话框、提示框、确认框等弹出式内容。在对话框中&#xff0c;可以包含文本、表单元素、按钮等内容&#xff0c;用户可以和这些内容进行交互。 3、兼容性 4、示例代码 …

03-MVC执行流程-参数解析与Model

重要组件 准备Model&#xff0c;Controller Configuration public class WebConfig {ControllerAdvicestatic class MyControllerAdvice {ModelAttribute("b")public String bar() {return "bar";}}Controllerstatic class Controller1 {ResponseStatus(H…

现代永磁同步电机控制原理pdf及全套matlab仿真模型

现代永磁同步电机控制原理pdf及matlab仿真模型。全书包含SVPWM, DTC, Lun, smo, EKF, HFI等经典控制算法。将书中10章节涉及到的模型复原搭建模型。 模型获取链接&#xff1a;现代永磁同步电机控制原理pdf及全套matlab仿真模型

电商API数据采集接口||大数据的发展,带动电子商务产业链,促进了社会的进步

最近几年计算机技术在诸多领域得到了有效的应用&#xff0c;同时在多方面深刻影响着我国经济水平的发展。除此之外&#xff0c;人民群众的日常生活水平也受大数据技术的影响。 主流电商API数据采集接口||在这其中电子商务领域也在大数据技术的支持下&#xff0c;得到了明显的进…

windows环境下DVWA靶场搭建

目录 一&#xff0c;安装PHPstudy 二&#xff0c;DVWA靶场上传 一&#xff0c;安装PHPstudy 具体安装步骤&#xff0c;请看上篇文章https://blog.csdn.net/m0_72210904/article/details/138258609?spm1001.2014.3001.5501 二&#xff0c;DVWA靶场上传 压缩包&#xff1a;&…

计算机混合运算(计算器)

学习贺利坚老师,计算机混合运算, 做出处理混合运算 数据结构例程——表达式求值&#xff08;用栈结构&#xff09;_用栈表达式求值-CSDN博客文章浏览阅读1.5w次&#xff0c;点赞14次&#xff0c;收藏61次。本文针对数据结构基础系列网络课程(3)&#xff1a;栈和队列中第5课时栈…

工业异常检测

工业异常检测在业界和学界都一直是热门&#xff0c;近期其更是迎来了全新突破&#xff1a;与大模型相结合&#xff01;让异常检测变得更快更准更简单&#xff01; 比如模型AnomalyGPT&#xff0c;它克服了以往的局限&#xff0c;能够让大模型充分理解工业场景图像&#xff0c;判…

与 Apolo 共创生态:Apolo 7周年大会我的启示与心得分享

文章目录 前言一、Apolo加速企业自动驾驶解决方案落地二、应用X企业预制套件&#xff1a;启示与心得三、Studio X企业协同工具链&#xff1a;共创心得分享 前言 本篇文章我将围绕Apolo 7周年来给大家分享我所学习到的内容和一些心得。 Apolo 7周年活动链接&#xff1a;https:…

2024年【陕西省安全员C证】报名考试及陕西省安全员C证考试资料

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年陕西省安全员C证报名考试为正在备考陕西省安全员C证操作证的学员准备的理论考试专题&#xff0c;每个月更新的陕西省安全员C证考试资料祝您顺利通过陕西省安全员C证考试。 1、【多选题】下列做法正确的有&#…