C语言的编译和链接

每日一言

要保持希望在每天清晨太阳升起。 --自己


前言

当我们写下C语言代码(源文件、以.c为后缀)的时候,他需要经过一个翻译环境,被处理后形成一个可执行程序(以.exe为后缀)。形成的这个可执行程序里面放的都是二进制信息,它可以被机器读懂
(全文都在Windows环境下)

什么是翻译环境

翻译环境(Translation Environment)是指用于将源代码翻译为目标代码的一系列工具和软件组成的环境。它其实是由编译和链接两个大的过程组成的,而编译又可以分为:预处理、编译、汇编三个过程。

编译

源文件经过编译器编译后,形成一个目标文件(以.obg为后缀)
在这里插入图片描述

预处理

预处理器是执行预处理的工具,它根据预处理指令(以#开头)对源代码进行处理。

预处理的主要作用有:

  1. 文件包含:使用预处理指令#include可以将一个文件的内容插入到另一个文件中。这是C语言中模块化编程的一种方式,可以将功能相关的代码组织在不同的文件中,并通过包含文件来使用这些代码。

  2. 宏替换:使用#define指令可以定义宏,预处理器会在编译之前扫描源代码,将代码中出现的宏名称替换为对应的宏定义。宏替换可以简化代码,提高代码的可读性和维护性。

  3. 条件编译:使用#if#ifdef#ifndef等条件指令可以根据条件编译不同的代码。通过条件编译,我们可以根据不同的平台、编译选项或宏定义来选择性地编译不同的代码块。

  4. 注释删除:预处理器会将源代码中的注释删除,这样在编译阶段就不会再考虑这些注释了。

预处理是在编译之前进行的,它处理的是纯文本的源代码,生成的是经过预处理后的代码。预处理阶段的结果会成为编译器的输入,在编译器对处理后的代码进行词法分析、语法分析和语义分析等操作后,生成最终的目标代码。

编译

在预处理阶段之后,编译器会对经过预处理的源代码进行词法分析、语法分析、语义分析等处理,然后生成目标代码。

  1. 词法分析:将源代码分解成一个个的标记,如关键字、标识 符、运算符等。词法分析器会扫描源代码并生成标记序列供后续的语法分析使用。
  2. 语法分析:根据所使用的语法规则,将标记序列生成语法树。语法分析器会遵循语法规则检查源代码的语法是否正确,并生成语法树用于语义分析。
  3. 语义分析:对语法树进行静态语义检查,包括类型检查、作用域分析等。语义分析器会检查标识符的使用是否正确,进行类型推导和类型转换等操作。

汇编

汇编器的主要任务是将汇编语言代码转换为机器指令。就是根据汇编指令和机器指令的对照表一一的进行翻译,也不做指令优化。

链接

链接是将多个目标代码文件或库文件合并成一个可执行文件的过程。
链接的主要任务是将所有的目标代码文件合并,并解决函数和变量的引用关系。

  1. 符号解析:在目标代码中,各个函数和变量使用符号来表示。链接器会遍历所有目标代码文件,通过符号表来解析函数和变量的引用关系。

  2. 地址重定位:在链接过程中,各个目标代码文件的地址空间是相互独立的,需要进行地址的重定位。链接器会根据每个目标代码文件在内存中的位置,调整代码中的地址引用,使其正确指向目标地址。

  3. 文件合并:链接器会将所有目标代码文件中的可执行代码和数据段合并成一个整体。这涉及到对各个目标代码文件的段进行合并和对齐操作。

  4. 符号解析与重定义:在链接过程中,可能会遇到多个目标代码文件中定义了相同的函数或变量。链接器会解析这些符号,并根据一定的规则进行重定义,以确保每个符号只有一个定义。

  5. 库文件链接:除了链接目标代码文件外,链接器还可以将库文件链接到可执行文件中。库文件中包含了一组已编译好的函数和变量的实现,通过链接库文件可以避免重复编写相同的代码。

运行环境

  1. 程序必须载入内存中,在有操作系统的环境中:一般由这个操作系统完成,在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成
  2. 程序的执行便开始,接着便调用main函数
  3. 开始执行程序代码,这个时候程序将使用一个运行时堆栈,存储函数的局部变量和返回地址。程序同时也可以使用静态内存,存储于静态内存中的变量在程序的整个执行过程中一直保留他们的值
  4. 终止程序,正常终止main函数;也有可能是意外终止。

结语

本文只介绍了一点点皮毛,如果读者有兴趣可以去读一读:《程序员的自我修养》《编译原理》
请给自己些耐心,一口吃不成胖子。
山外青山楼外楼,莫把百尺当尽头。
保持空杯心态加油努力吧!


都看到这里啦!真棒(*^▽^*)

可以给作者一个免费的赞赞吗,这将会鼓励我继续创作,谢谢大家

编程小白写作,如有纰漏或错误,欢迎指正


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PLC-IoT 网关开发札记(5):将本地数据库作为资产打包发布到 App

App需求:保存物模型 什么是物模型 在项目开发中,用到了本地数据库,这个本地数据库记录了系统的物模型。所谓物模型就是对某一个设备的可操纵属性的定义,每一个设备包括了一个或者多个属性,通过获取这些属性的当前值可…

基于CanvasLabel的Leaflet矢量数据免切片属性标注实践

目录 前言 一、Leaflet.CanvasLabel 1、开源地址 2、设置参数说明 二、组件集成 1、新建html文件 2、声明样式 3、定义矢量文本渲染器 4、定义地图 5、添加矢量数据 6、最终效果 总结 前言 在一般的业务场景中,针对小量的矢量数据,比如POI兴…

Opncv模板匹配 单模板匹配 多模板匹配

目录 问题引入 单模板匹配 ①模板匹配函数: ②查找最值和极值的坐标和值: 整体流程原理介绍 实例代码介绍: 多模板匹配 ①定义阈值 ②zip函数 整体流程原理介绍 实例代码: 问题引入 下面有请我们的陶大郎登场 这张图片是我们的陶大郎,我们接下来将利用陶大郎来介绍…

Eclipses安装教程

一、下载开发工具包 1、开发工具包JDK 下载地址链接:https://www.oracle.com/cn/java/technologies/downloads/ 下载教程: 1)点击链接,可以跳转到页面 2)下滑页面,找到开发工具包 3) 记住下载之…

Linux shell编程学习笔记41:lsblk命令

边缘计算的挑战和机遇 边缘计算面临着数据安全与隐私保护、网络稳定性等挑战,但同时也带来了更强的实时性和本地处理能力,为企业降低了成本和压力,提高了数据处理效率。因此,边缘计算既带来了挑战也带来了机遇,需要我…

关于js的BigInt的使用与注意事项

说明 BigInt是一种内置对象,提供了一种方法来表示大于2^53 - 1 的整数,2^53 - 1 为Number可以表示的最大数字,BigInt可以突破限制,可以用任意精度表示整数,超出Number的安全整数限制,也可以安全地存储和操…

回归预测 | Matlab基于ABC-SVR人工蜂群算法优化支持向量机的数据多输入单输出回归预测

回归预测 | Matlab基于ABC-SVR人工蜂群算法优化支持向量机的数据多输入单输出回归预测 目录 回归预测 | Matlab基于ABC-SVR人工蜂群算法优化支持向量机的数据多输入单输出回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab基于ABC-SVR人工蜂群算法优化支持…

C++ 知识列表【图】

举例C的设计模式和智能指针 当谈到 C 的设计模式时,以下是一些常见的设计模式: 工厂模式(Factory Pattern):用于创建对象的模式,隐藏了对象的具体实现细节,只暴露一个公共接口来创建对象。 单例…

基于Word2vec词聚类的关键词实现

一.基于Word2vec词聚类的关键词步骤 基于Word2Vec的词聚类关键词提取包括以下步骤: 1.准备文本数据:收集或准备文本数据,可以是单一文档或文档集合,涵盖关键词提取的领域。2.文本预处理:清洗文本数据,去除…

mac 安装配置oh-my-zsh

1. 安装brew /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)" 按照步骤安装即可 安装完成查看版本 brew -v 2. 安装zsh brew install zsh 查看版本 zsh --version 3. 安装oh-my-zsh github官网链…

泛型..

1.泛型 所谓泛型 其实就是一种类型参数(我们平常所见到的参数指的就是方法中的参数 他接收有外界传递来的值 然后在方法中进行使用) 并且还提高了代码的复用率 何以见得提高了代码的复用率 其实就是通过对比使用了泛型技术和没有使用泛型技术之间的区别: 以下是没有…

Vue学习笔记9--vuex(专门在Vue中实现集中式状态(数据)管理的一个Vue插件)

一、vuex是什么? 概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于…

MySQL索引优化:深入理解索引下推原理与实践

随着MySQL的不断发展和升级,每个版本都为数据库性能和查询优化带来了新的特性。在MySQL 5.6中,引入了一个重要的优化特性——索引下推(Index Condition Pushdown,简称ICP)。ICP能够在某些查询场景下显著提高查询性能&a…

1.使用分布式文件系统Minio管理文件

分布式文件系统DFS分类 文件系统 文件系统是操作系统用于组织管理存储设备(磁盘)或分区上文件信息的方法和数据结构,负责对文件存储设备空间进行组织和分配,并对存入文件进行保护和检索 文件系统是负责管理和存储文件的系统软件,操作系统通过文件系统提供的接口去…

html 会跳舞的时间动画特效

下面是是代码&#xff1a; <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://www.w3.org/1999/xhtml"> <head> <meta h…

Python环境下一维时间序列信号的时频脊线追踪方法

瞬时频率是分析调频信号的一个重要参数&#xff0c;它表示了信号中的特征频率随时间的变化。使用短时傅里叶变换或小波变换获得信号的时频表示TFR后&#xff0c;从TFR中估计信号各分量的瞬时频率&#xff0c;即可获得信号中的特征信息。在TFR中&#xff0c;调频信号的特征分量通…

考试查分场景重保背后,我们如何进行可用性测试

作者&#xff1a;暮角 随着通过互联网音视频与知识建立连接的新学习方式在全国范围内迅速普及&#xff0c;在线教育/认证考试的用户规模呈井喷式增长。但教育容不得半点马虎与妥协&#xff0c;伴随用户规模不断增长&#xff0c;保证系统稳定性、有效避免千万考生考试时遭遇故障…

JAVA RPC Thrift基操实现与微服务间调用

一、Thrift 基操实现 1.1 thrift文件 namespace java com.zn.opit.thrift.helloworldservice HelloWorldService {string sayHello(1:string username) }1.2 执行命令生成Java文件 thrift -r --gen java helloworld.thrift生成代码HelloWorldService接口如下 /*** Autogene…

Oracle Vagrant Box 无法登录的2个问题

安装Oracle Database 19c 的 VagrantBox &#xff0c;非常顺利&#xff0c;耗时如下&#xff1a; real 30m36.783s user 0m0.000s sys 0m0.047s前面一切顺利&#xff0c;但是vagrant ssh和vagrant putty均不能登录虚机。我的环境是Windows 11&#xff0c;Vagrant 2.…

安卓Spinner文字看不清

Holo主题安卓13的Spinner文字看不清&#xff0c;明明已经解决了&#xff0c;又忘记了。 spinner.setOnItemSelectedListener(new Spinner.OnItemSelectedListener() {public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {TextView textV…