linux入门---程序翻译的过程
我们在vs编译器中写的代码按下ctrl f5就可以直接运行起来,并且会将运行的结果显示到显示器上,这里看上去只有一个步骤但实际上这里会存在很多的细节,比如说生成结果在这里插入代码片
之前我们的代码会经过预处理,编译,汇编,链接的过程,不同的过程会对应不同的操作,那么接下来我们就会一个一个的介绍这些操作所对应的操作。
预处理
程序运行的第一步就是预处理,预处理的目的就是:将头文件展开,去掉注释,宏替换,删除条件编译,比如说我们创建一个临时文件test.c:
并且在这个文件里面输入一些内容:
1 #include<stdio.h> 2 #define NUM_A 20 3 #define NUM_B 30 4 int main()5 {6 #ifdef add7 printf("相加的结果为:%d\n",NUM_A+NUM_B);//计算相加的结果8 #else9 printf("相减的结果为:%d\n",NUM_A-NUM_B);//计算相减的结果 10 #endif 11 return 0; 12 }
然后我们就退出并且保存这个文件:
到这里我们的准备工作就完成了。平时我们运行文件使用的指令是:gcc test.c
使用这个指令会自动的生成一个文件叫a.out,并且这个文件是一个可执行程序,我们运行一下这个程序就可以可以看到我们的屏幕上面出现了上面代码的运行的结果:
但是这里有个问题,使用这个指令我们看不到预处理的结果它直接变成了可执行程序,所以得在这个指令里面添加一个-E选项,这个选项的功能就是从重现在开始进行程序的翻译,将程序的预处理执行完后就停下来,所以使用这个选项我们就可以看到代码经过预处理之后的结果,那么这里的指令就是这样:gcc -E test.c
执行的结果如下:
我们可以看到这里出现很多乱七八糟的内容,那是因为这个指令将执行的结果全部都打印到屏幕上了,由于内容很多就显得很乱,不好查看,所以这里我们还可以在这个指令里面添加一个-o选项,这个选项的功能就是将指令的运行的结果放到一个文件里面,在-o的后面加上你要放的文件,如果这个文件不存在的话,这个指令会自动生成对应的文件,比如说我们将上面的指令修改成这样:gcc -E test.c -o test.i
当前目录下是没有test.i这个文件的,所以使用这个指令后我们会自动的生成test.i这个文件:
并且这个文件里面装的内容就是之前显示在屏幕上的内容:
我们可以使用vs指令将test.c文件显示在屏幕上进行对比:
我们使用shift+g将右边屏幕的光标移动到最后一行:
我们可以看到在test.i文件的最后出现了test.c文件中的大致内容,但是却略有不同这是test.i的相关内容:
这是test.c的全部内容:
仔细的观察一下我们可以看到有以下几点的不同:
- test.c中的2 3 行定义的宏被删除了。
- test.c中的7 9行的注释被删除了。
- test.c中的7 9行中使用的宏被替换成了我们定义的值也就是说NUM_A替换成了20,NUM_B替换成了30。
- test.c中没有被执行的条件编译被删除了也就是第6 7 8 10行的内容被删除了。
- test.c中的头文件被删除了但是在test.i中出现了更多杂七杂八的东西,所以在预编译的过程中将头文件中的内容加载到test.i的文件里面。
那么这就是预编译所做的一些操作将头文件展开,去掉注释,宏替换,删除条件编译,那么这里大家要注意的一点就是在linux操作系统中文件的后缀是没有意义的,也就是说这里的后缀i对于操作系统来说是没有什么特殊意义的,但是这个后缀对我们使用者来说却有很多的意义,比如说我们看到了一个文件的后缀是i就可以想到这个文件是经过预处理后生成的文件,所以大家在执行这些操作生成文件的时候还是要将后缀写成对应的形式以免混淆别人,那么上面就是预处理要干的事情。
编译
经历完预处理之后要执行的操作就是编译,编译要干的事情就是将c语言翻译成汇编语言,那么这里要执行的指令就是:gcc -S test.i -o test.s
那么这里-S选项的作用就是从现在开始进行程序的翻译,将汇编工作完成之后工作就停止,后面加了一个-o选项,所以这里会将执行完之后的结果放到test.s这个文件里面,执行完这个指令我们就可以看到这里自动的生成了一个test.s文件,在这个文件里面有我们好多我们看不懂的内容:
虽然下面的内容我们看不懂,但是可以知道的一件事就是这个test.o文件里面的内容是汇编语言:
我们知道计算器能够识别的语言是二进制语言,而test.o文件里面装的是汇编语言,所以这里的test.o文件无法被运行。
汇编
通过上面的讲解我们知道编译是将c语言翻译成汇编语言,那么这里的汇编要干的事情就是将生成的汇编语言翻译二进制语言,那么这里需要的指令就是:gcc -c test.s -o test.o
,-c选项的作用就是从现在开始进行翻译,将文件中的汇编语言翻译成二进制语言就停止,比如说下面的操作:
这里就自动生成一个test.o文件,我们打开这个文件就可以看到文件中的内容就变成了各种奇奇怪怪的符号:
这就是文件经过汇编之后的结果,那么这时肯定会有小伙伴想啊,既然这个文件的内容是二进制的话,我们是不是就可以运行这个文件呢?那么这里可以试一下看看能不能运行
结果很明显这个文件是无法运行的,原因也非常的简单因为我们上述的三个过程(预处理 编译 汇编)所干的事情是翻译的过程,也就是把你的代码进行修剪然后翻译成二进制文件,但是这里有个问题就是你的代码里面用了很多别人的函数,你没有在这个文件里面实现这些函数,比如说printf函数,scanf函数,main函数等等,这些函数你都没有实现,虽然你包含了头文件stdio.h,但是这个文件里面只有这些函数的声明,没有这些实现,所以将我们的代码翻译成二进制文件还是无法满足运行的需求,所以这里我们还得进行下一步链接。
链接
链接干的事情就是把我们自己写的代码代码和c标准库的代码合并起来,这个标准库里面装的就是各种c语言函数的具体实现等等,所以当二进制文件经过链接后,里面使用的函数就有了具体的实现,就可以正常的被执行了,那么这里的用的之指令就是:gcc test.o
这里我们不使用-o选项的话,这里就会自动生成一个名为a.out的可执行程序,当然这里我们也可以人为的生成一个可执行程序,那么这里就得加上一个-o选项,那么这里的指令就是:gcc test.o -o mytest
当生成完可执行程序之后就可以运行以下这里的可执行文件:
那么上述就是这篇文章的全部内容希望大家可以理解谢谢。
相关文章:

linux入门---程序翻译的过程
我们在vs编译器中写的代码按下ctrl f5就可以直接运行起来,并且会将运行的结果显示到显示器上,这里看上去只有一个步骤但实际上这里会存在很多的细节,比如说生成结果在这里插入代码片之前我们的代码会经过预处理,编译,汇…...

springboot复习(黑马)
学习目标基于SpringBoot框架的程序开发步骤熟练使用SpringBoot配置信息修改服务器配置基于SpringBoot的完成SSM整合项目开发一、SpringBoot简介1. 入门案例问题导入SpringMVC的HelloWord程序大家还记得吗?SpringBoot是由Pivotal团队提供的全新框架,其设计…...

C++指针详解
旧文更新:两三年的旧文了,一直放在电脑里,现在直接传上CSDN 一、指针的概念 1.1 指针 程序运行时每个变量都会有一块内存空间,变量的值就存放在这块空间中。程序可以通过变量名直接访问这块空间内的数据,这种访问方…...

tauri+vite+vue3开发环境下创建、启动运行和打包发布
目录 1.创建项目 2.安装依赖 3.启动项目 4.打包生成windows安装包 5.安装打包生成的安装包 1.创建项目 运行下面命令创建一个tauri项目 pnpm create tauri-app 我创建该项目时的node版本为16.15.0 兼容性注意 Vite 需要 Node.js 版本 14.18,16。然而&#x…...

安卓进阶系列-系统基础
文章目录计算机结构冯诺依曼结构哈弗结构冯诺依曼结构与哈弗结构对比安卓采用的架构安卓操作系统进程间通讯(IPC)内存共享linux内存共享安卓内存共享管道Unix Domain Socket同步常见同步机制信号量Mutex管程安卓同步机制安卓中的Mutex安卓中的ConditionB…...

10 Wifi网络的封装
概述 Wifi有多种工作模式,比如:STA模式、AccessPoint模式、Monitor模式、Ad-hoc模式、Mesh模式等。但在IPC设备上,主要使用STA和AccessPoint这两种模式。下面分别进行介绍。 STA模式:任何一种无线网卡都可以运行在此模式,这种模式也是无线网卡的默认模式。在此模式下,无线…...

手把手的教你安装PyCharm --Pycharm安装详细教程(一)(非常详细,非常实用)
简介 Jetbrains家族和Pycharm版本划分: pycharm是Jetbrains家族中的一个明星产品,Jetbrains开发了许多好用的编辑器,包括Java编辑器(IntelliJ IDEA)、JavaScript编辑器(WebStorm)、PHP编辑器&…...

开发板与ubantu文件传送
接下来的所以实验都通过下面这种方式发送APP文件到开发板运行 目录 1、在ubantu配置 ①在虚拟机上添加一个桥接模式的虚拟网卡 ②设定网卡 ③在网卡上配置静态地址 2、开发板设置 ①查看网卡 ②配置网卡静态ip 3、 测试 ①ping ②文件传送 传送报错情况 配置环境&#…...

如何成为一名优秀的网络安全工程师?
前言 这是我的建议如何成为网络安全工程师,你应该按照下面顺序学习。 简要说明 第一件事你应该学习如何编程,我建议首先学python,然后是java。 (非必须)接下来学习一些算法和数据结构是很有帮助的,它将…...

面试问题之高并发内存池项目
项目部分 1.这个项目是什么? 高并发内存池的原型是谷歌一个开源项目,tcmalloc,而这个项目,就是tcmalloc中最核心的框架和部分拿出来进行模拟。他的作用就是在去代替原型的内存分配函数malloc和free。这个项目涉及的技术有,c&…...
如果阿里巴巴给蒋凡“百亿补贴”
出品 | 何玺 排版 | 叶媛 2021底,阿里内部进行组织架构大调整,任命蒋凡为阿里海外商业负责人,分管全球速卖通和国际贸易(ICBU)两个海外业务,以及Lazada等面向海外市场的多家子公司。 一年时间过去&#x…...
Linux版本现状
Linux的发行版本可以大体分为两类,一类是商业公司维护的发行版本,一类是社区组织维护的发行版本,前者以著名的Red Hat(RHEL红帽)为代表,后者以Debian为代表。Red HatRedhat,应该称为Redhat系列&…...
Winform中实现保存配置到文件/项目启动时从文件中读取配置(序列化与反序列化对象)
场景 Winform中实现序列化指定类型的对象到指定的Xml文件和从指定的Xml文件中反序列化指定类型的对象: Winform中实现序列化指定类型的对象到指定的Xml文件和从指定的Xml文件中反序列化指定类型的对象_winform xml序列化_霸道流氓气质的博客-CSDN博客 上面讲的序…...

基于python的超市历年数据可视化分析
人生苦短 我用python Python其他实用资料:点击此处跳转文末名片获取 数据可视化分析目录人生苦短 我用python一、数据描述1、数据概览二、数据预处理0、导入包和数据1、列名重命名2、提取数据中时间,方便后续分析绘图三、数据可视化1、美国各个地区销售额的分布&…...

GPT-4技术报告
摘要 链接:https://cdn.openai.com/papers/gpt-4.pdf 我们汇报了GPT-4的发展,这是一个大规模的多模态模型,可以接受图像和文本输入并产生文本输出。虽然在许多现实场景中,GPT-4的能力不如人类,但它在各种专业和学术基…...
前端性能优化
总结 使用打包工具对代码进行打包压缩;引入css时采用link标签,并放入头部,使其与文档一起加载,减少页面卡顿时间;尽量减少dom结构的重排和重绘;使用css雪碧图,减少网络请求;对不同分…...

尚医通-(三十三)就诊人管理功能实现
目录: (1)前台用户系统-就诊人管理-需求说明 (2)就诊人管理-接口开发-列表接口 (3)就诊人管理-接口开发-其他接口 (4)前台用户系统-就诊人管理-前端整合 ࿰…...

《Spring Boot 趣味实战课》读书笔记(二)
牛刀小试——五分钟入门 Spring Boot 万物皆可 Hello World 创建一个 Web 工程 填写项目信息 选择依赖 从 IDEA 打开下载好的 Spring Boot 工程: 完成核心代码 创建 HelloController 类并编写 hello 方法 创建一个 HelloController 类,或者选择 Fi…...

Spring Cloud -- GateWay
为什么需要网关在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢?如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去调用。这样的话会产生很多问题,例…...
【C语言】memcpy , memset等内存操作函数使用方法与注意事项
这个章节,我们探讨C语言内存操作函数。 重点介绍处理内存操作函数使用和注意事项 和内存函数如何模拟实现。 内存函数所需头文件 #include<string.h> 文章目录memcpymemcpy 函数模拟实现memmovememmove 函数模拟实现memcmpmemcmp 函数模拟实现memsetmemset 函…...

基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...

Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...

LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...

Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...